Version 3 (modified by mikhail.vorozhtsov, 3 years ago) (diff)

Added MultiClauseLambdas with \ in each clause

This page is a summary of proposals from #4359

## The problem

The current lambda abstraction syntax allows us to conveniently bind parts of the arguments by using patterns, but does not provide a way to branch quickly (without naming the argument). Usually we just cringe a bit and write

```\tmp -> case tmp of
Pat1 -> ...
Pat2 -> ...
```

or even

```\meaningfulName -> case meaningfulName of
Pat1 -> ...
Pat2 -> ...
```

However, when this situation nests (e.g. monadic bind) and variables have the same type, naming becomes painful and often degrades to not-so-meaningful meaningfulName1, meaningfulName2, ...

A similar problem exists with proc expressions from arrow notation, which can be regarded as generalized lambda expressions. We sometimes have expressions of the following structure:

```proc meaningfulName -> case meaningfulName of
Pat1 -> ...
Pat2 -> ...
```

Here, the dots stand for arrow expressions, not ordinary expressions.

## The proposals

### LambdaCase: case of

A simple sugar for one-argument lambda abstractions.

```case of
Pat1 -> Expr1
Pat2 -> Expr2
```

desugars to

```\freshName -> case freshName of
Pat1 -> Expr1
Pat2 -> Expr2
```
• Pros
• No conflicts with the current syntax (the sequence case of is illegal)
• Cons
• Looks weird (no hint of being a lambda abstraction)
• Single-argument solution (see the note)
• Cannot be generalized to cover also proc expressions

### LambdaCase: \case

A "less weird" version of case of. As above,

```\case
Pat1 -> Expr1
Pat2 -> Expr2
```

desugars to

```\freshName -> case freshName of
Pat1 -> Expr1
Pat2 -> Expr2
```

(\case is a layout herald).

• Pros
• No conflicts with the current syntax (the sequence \ case is illegal)
• An analog syntax for proc expressions can be gained by replacing \ with proc
• Cons
• Single-argument solution (see the note). One way to extend it to support multiple arguments is
```\case
Pat1_1, Pat1_2, ... -> Expr1
Pat2_1, Pat2_2, ... -> Expr2
```
(separation with commas is supposed to preserve case-like feel, e.g. Just x, Just y -> vs (Just x) (Just y) ->) which is considered unorthodox by GHC HQ.

### MultiClauseLambdas

Extend the current syntax with alternative clauses:

```\Pat1_1 Pat1_2 ... -> Expr1
Pat2_1 Pat2_2 ... -> Expr2
...
```

(\ becomes a layout herald)

• Pros
• Multi-argument solution (see the note)
• An analog syntax for proc expressions can be gained by replacing \ with proc
• Cons
• Breaks current idioms. For example,
```mask \$ \restore -> do
stmt1
stmt2
```
becomes illegal because stmt1 is indented less than restore. One way to avoid this is to not make \ a herald, forcing users to use explicit layout for multi-clause abstractions, i.e.
```\ { Pat1_1 Pat1_2 ... -> Expr1
; Pat2_1 Pat2_2 ... -> Expr2 }
```
Another is to start each clause with a \:
```\ Pat1_1 Pat1_2 ... -> Expr1
\ Pat2_1 Pat2_2 ... -> Expr2
\ ...
```

### MultiClauseLambdas with a keyword

Addresses the layout problem of MultiClauseLambdas. Requires multi-clause abstractions to have a keyword after \:

```\KEYWORD Pat1_1 Pat1_2 ... -> Expr1
Pat2_1 Pat2_2 ... -> Expr2
...
```

(\KEYWORD is a layout herald)

• Pros
• No conflicts with the current syntax
• Multi-argument solution (see the note)
• An analog syntax for proc expressions can be gained by replacing \ with proc
• Cons
• Deciding on the keyword may take years

### Extra: LambdaMatch

A full revamp of pattern matching: Haskell' ticket.

## Notes

### Single vs multi-argument

(field report by Mikhail Vorozhtsov) I've been using \case for over a year and tried MultiClauseLambdas for about two months. In my code base \case seems to cover 99% of cases (no pun intended) and curry \$ \case ... does the job for the rest, so having only a single-argument solution may be not as restrictive as it seems. On the other hand, I had a hard time with MultiClauseLambdas extra clauses: I just kept writing Just x -> Expr instead of the correct (Just x) -> Expr. It seems that lines like [spaces]Pat -> Expr are just hardwired to case-expressions in my brain.