Syntax for lambda case proposal could be "\of"

Hi, On http://hackage.haskell.org/trac/haskell-prime/wiki/LambdaCase the proposed syntax for lambda case is: case of alts but this has a really bad downside for interactive editors: it doesn't allow one to distinguish between an incomplete construct and a completed construct thus removing one opportunity for an editor to alert the user (eg by highlighting) that there is something missing in the program text. Therefore I propose: \of alts which doesn't suffer this problem since the keyword "of" can never follow a '\' in the existing grammar. However I can't edit the H' wiki, so if anyone agrees that the above syntax is better please could they add the above to the page. Thanks, Brian.

On Wed, Aug 15, 2007 at 06:23:24PM +0100, Brian Hulley wrote:
Hi, On http://hackage.haskell.org/trac/haskell-prime/wiki/LambdaCase the proposed syntax for lambda case is:
case of alts
but this has a really bad downside for interactive editors: it doesn't allow one to distinguish between an incomplete construct and a completed construct thus removing one opportunity for an editor to alert the user (eg by highlighting) that there is something missing in the program text.
It's not like the current language has that property; consider (map myFunction) - is that an error or a partial application? I don't hold out much hope for context-free smart editors. You'll need a typechecker to do much of use, and that can easily distinguish lambda cases from regular cases... OTOH, your proposal provides (IMO) much more natural syntax for multi-pattern anonymous functions, especially if we stipulate that unlike a case (but like a lambda) you can have multiple arguments; then you could write stuff like: sumTo0 = foldr (\of 0 k -> 0 n k -> n + k) 0 Anyone else like this? Stefan

On Wed, 2007-08-15 at 10:50 -0700, Stefan O'Rear wrote:
OTOH, your proposal provides (IMO) much more natural syntax for multi-pattern anonymous functions, especially if we stipulate that unlike a case (but like a lambda) you can have multiple arguments; then you could write stuff like:
sumTo0 = foldr (\of 0 k -> 0 n k -> n + k) 0
Anyone else like this?
Why not just: sumTo0 = foldr (\0 k -> 0 n k -> n + k) 0 I find using "case" or "of" for multiple arg lambda pattern matches odd since "case foo of" is only used for single arg pattern matches. I suppose the equivalent explicit layout syntax would be: sumTo0 = foldr (\{ 0 k -> 0; n k -> n + k }) 0 Duncan

On Wed, Aug 15, 2007 at 06:58:40PM +0100, Duncan Coutts wrote:
On Wed, 2007-08-15 at 10:50 -0700, Stefan O'Rear wrote:
OTOH, your proposal provides (IMO) much more natural syntax for multi-pattern anonymous functions, especially if we stipulate that unlike a case (but like a lambda) you can have multiple arguments; then you could write stuff like:
sumTo0 = foldr (\of 0 k -> 0 n k -> n + k) 0
Anyone else like this?
Why not just:
sumTo0 = foldr (\0 k -> 0 n k -> n + k) 0
Because it would break a very large amount of old code, and I think H' was supposed to be upward compatible: foo = getSomethingCPS $ \ arg -> moreStuff is now a syntax error (\ { varid -> } matches no productions). Stefan

Stefan O'Rear wrote:
On Wed, Aug 15, 2007 at 06:58:40PM +0100, Duncan Coutts wrote:
On Wed, 2007-08-15 at 10:50 -0700, Stefan O'Rear wrote:
OTOH, your proposal provides (IMO) much more natural syntax for multi-pattern anonymous functions, especially if we stipulate that unlike a case (but like a lambda) you can have multiple arguments; then you could write stuff like:
sumTo0 = foldr (\of 0 k -> 0 n k -> n + k) 0
sumTo0 = foldr (\0 k -> 0 n k -> n + k) 0
foo = getSomethingCPS $ \ arg -> moreStuff
is now a syntax error (\ { varid -> } matches no productions).
A multi-way lambda could be introduced using \\ thus: sumTo0 = foldr (\\ 0 k -> 0; n k -> n + k) 0 [from a previous post]
It's not like the current language has that property; consider (map myFunction) - is that an error or a partial application?
By "construct" I meant only those grammatical elements involving keywords, and was thinking about situations where you might for example have various syntax templates bound to function keys eg in Haskell the following are incomplete: case of if then else data where deriving ("let in" could still be marked as incomplete even if it is ok according to the grammar since it would be weird to bother writing a let with no bindings.) There is a similar problem with the way template haskell uses unmatched quotes such as 'a so it's no longer possible to determine whether this should be marked as an incomplete character literal or a complete TH name. I suppose my main point is that it's useful for a syntax to have plenty of "unfilled gaps" that result in an error when written rather than filling all those gaps with different meanings... Brian.

Brian Hulley wrote:
Stefan O'Rear wrote:
On Wed, Aug 15, 2007 at 06:58:40PM +0100, Duncan Coutts wrote:
On Wed, 2007-08-15 at 10:50 -0700, Stefan O'Rear wrote:
OTOH, your proposal provides (IMO) much more natural syntax for multi-pattern anonymous functions, especially if we stipulate that unlike a case (but like a lambda) you can have multiple arguments; then you could write stuff like:
sumTo0 = foldr (\of 0 k -> 0 n k -> n + k) 0
sumTo0 = foldr (\0 k -> 0 n k -> n + k) 0
foo = getSomethingCPS $ \ arg -> moreStuff
is now a syntax error (\ { varid -> } matches no productions).
A multi-way lambda could be introduced using \\ thus:
sumTo0 = foldr (\\ 0 k -> 0; n k -> n + k) 0
I like the idea, but unfortunately '\\' is currently a regular operator symbol. In fact it is used as (set or map) 'difference' operator (according to http://www.haskell.org/ghc/docs/latest/html/libraries/doc-index-92.html): \\ 1 (Function) Data.IntMap 2 (Function) Data.IntSet 3 (Function) Data.List 4 (Function) Data.Map 5 (Function) Data.Set Cheers Ben

On Wed, Aug 15, 2007 at 11:06:36AM -0700, Stefan O'Rear wrote:
On Wed, Aug 15, 2007 at 06:58:40PM +0100, Duncan Coutts wrote:
On Wed, 2007-08-15 at 10:50 -0700, Stefan O'Rear wrote:
OTOH, your proposal provides (IMO) much more natural syntax for multi-pattern anonymous functions, especially if we stipulate that unlike a case (but like a lambda) you can have multiple arguments; then you could write stuff like:
sumTo0 = foldr (\of 0 k -> 0 n k -> n + k) 0
Anyone else like this?
Why not just:
sumTo0 = foldr (\0 k -> 0 n k -> n + k) 0
Because it would break a very large amount of old code, and I think H' was supposed to be upward compatible:
foo = getSomethingCPS $ \ arg -> moreStuff
is now a syntax error (\ { varid -> } matches no productions).
I was going to say you could leave the other production, but layout is separated from parsing. It's not even simple to say "use nondeterminism", because of that rule about a layout level ending if there would otherwise be a parse error. If that parse error rule backtracks far enough, old lambdas could simply have the production \{} pat -> expr, if it's only one token of lookahed perhaps \ { pat } -> expr would be mostly backwards-compatible (but it would be very wierd to understand the errors when it wasn't). Lambdas with multiple arguments and pattern matching sound really nice, but "case of" and "\of" are both extremely ugly names. They only make sense if you are familiar with the rest of the language and think of this as shoehorning in some new kind of lambda with pattern matching (remember constructor classes, and how it's all just typeclasses now). What do the rest of you on the cafe think? If a different name is necessary, I'd prefer something like "fun" that just tries to imply this is a slighly heavier, more powerful kind of anonymous function. (plus it's a step towards rec-expressions) Brandon

On Wed, 2007-08-15 at 11:06 -0700, Stefan O'Rear wrote:
Why not just:
sumTo0 = foldr (\0 k -> 0 n k -> n + k) 0
Because it would break a very large amount of old code, and I think H' was supposed to be upward compatible:
Aye, that'd be bad.
foo = getSomethingCPS $ \ arg -> moreStuff
is now a syntax error (\ { varid -> } matches no productions).
I'm not sure I follow. The patterns would have to match up in a column, so foo = getSomethingCPS $ \ arg -> moreStuff should be fine, to add another alternative it'd have to be: foo = getSomethingCPS $ \ Pat1 -> moreStuff Pat2 -> evenMoreStuff This case might be tricky though: foo = getSomethingCPS $ \ Pat1 -> foo moreStuff since we have to parse all of the moreStuff expression before discovering it has no following "->" and so it's party of the body of the first lambda alternative rather than a pattern starting a new alternative. I'm no parsing expert (especially when it comes to layout rules), perhaps this is all too tricky. Duncan

Duncan Coutts wrote:
On Wed, 2007-08-15 at 11:06 -0700, Stefan O'Rear wrote:
foo = getSomethingCPS $ \ arg -> moreStuff
is now a syntax error (\ { varid -> } matches no productions).
I'm not sure I follow.
The patterns would have to match up in a column, so
foo = getSomethingCPS $ \ arg -> moreStuff
should be fine, to add another alternative it'd have to be:
foo = getSomethingCPS $ \ Pat1 -> moreStuff Pat2 -> evenMoreStuff
I don't like this - it's not in the spirit of the existing layout rule at all. You should have to indent 'moreStuff' deeper than Pat1 I think;
foo = getSomethingCPS $ \ Pat1 -> moreStuff Pat2 -> evenMoreStuff
would be (visually) ok. But then Stefan's point is valid. So there should be two productions, I think, one for non-case lambdas and one for case-lambdas, like this: non-case-lambda: '\' apat+ '->' expr case-lambda: '\' '{' ( apat+ '->' expr ';' )* '}' Unfortunately this naive approach would add another point of arbitrarily large look-ahead to the grammar. The easiest way to resolve this is to add some keyword before or after '\', bringing is back to the previous proposals. I like both \of x y z -> ... a b c -> ... and case \ of x y z -> ... a b c -> ... (I'd add the space here, viewing \ as a pseudo-expression) In the spirit of the \\ proposal, while \\ itself is an operator, \ \ x y z -> ... a b c -> ... is still available as a syntax, but may be confusing. I have little preference between these options. Bertram

On 16 aug 2007, at 13.46, Bertram Felgenhauer wrote:
Duncan Coutts wrote:
On Wed, 2007-08-15 at 11:06 -0700, Stefan O'Rear wrote:
foo = getSomethingCPS $ \ arg -> moreStuff
is now a syntax error (\ { varid -> } matches no productions).
I'm not sure I follow.
The patterns would have to match up in a column, so
foo = getSomethingCPS $ \ arg -> moreStuff
should be fine, to add another alternative it'd have to be:
foo = getSomethingCPS $ \ Pat1 -> moreStuff Pat2 -> evenMoreStuff
I don't like this - it's not in the spirit of the existing layout rule at all. You should have to indent 'moreStuff' deeper than Pat1 I think;
foo = getSomethingCPS $ \ Pat1 -> moreStuff Pat2 -> evenMoreStuff
would be (visually) ok. But then Stefan's point is valid.
So there should be two productions, I think, one for non-case lambdas and one for case-lambdas, like this:
non-case-lambda: '\' apat+ '->' expr
case-lambda: '\' '{' ( apat+ '->' expr ';' )* '}'
Unfortunately this naive approach would add another point of arbitrarily large look-ahead to the grammar. The easiest way to resolve this is to add some keyword before or after '\', bringing is back to the previous proposals.
I like both
\of x y z -> ... a b c -> ...
and
case \ of x y z -> ... a b c -> ...
(I'd add the space here, viewing \ as a pseudo-expression)
In the spirit of the \\ proposal, while \\ itself is an operator,
\ \ x y z -> ... a b c -> ...
is still available as a syntax, but may be confusing.
.\ x y z -> ... a b c -> ... or just require unicode \lambda ;)

On Wed, 2007-08-15 at 18:23 +0100, Brian Hulley wrote:
Therefore I propose:
\of alts
which doesn't suffer this problem since the keyword "of" can never follow a '\' in the existing grammar.
Or how about: \case of alts which seems clearer to me. Similarly, the keyword "case" can never follow a '\' in the existing grammar. Mind you, this doesn't seem to save much over \x -> case x of alts It'd be more interesting if we could pattern match against multiple arguments with multiple alternatives like we can in a function definition. I've no idea what syntax for that should look like however. Duncan

Duncan Coutts wrote:
On Wed, 2007-08-15 at 18:23 +0100, Brian Hulley wrote:
Therefore I propose:
\of alts
which doesn't suffer this problem since the keyword "of" can never follow a '\' in the existing grammar.
Or how about:
\case of alts
which seems clearer to me.
Similarly, the keyword "case" can never follow a '\' in the existing grammar.
Mind you, this doesn't seem to save much over
\x -> case x of alts
It saves the writer using an explicit name which must be unique and the reader determining that the name is not used deeper in the expressions. (and a "->"). I tend to find myself wanting this after already having written a 'case' and decided I don't need/want a name for the thing being 'cased'. I wouldn't mind "case of", "\of" or "\case of", for using it. Allowing multiple arguments - is syntactically difficult to reconcile with 'case' because it restricts what single-argument forms can be used? Such as:
case foo of Just n -> n is allowed but f Just n = n isn't.
Isaac

I came really late to this discussion, so I assume someone has already proposed using (Control.Applicative.<|>) to select the first matching pattern of an unnamed cased object. Can someone point me to where that was proposed and why it was rejected? Dan Weston Isaac Dupree wrote:
Duncan Coutts wrote:
On Wed, 2007-08-15 at 18:23 +0100, Brian Hulley wrote:
Therefore I propose:
\of alts
which doesn't suffer this problem since the keyword "of" can never follow a '\' in the existing grammar.
Or how about:
\case of alts
which seems clearer to me.
Similarly, the keyword "case" can never follow a '\' in the existing grammar.
Mind you, this doesn't seem to save much over
\x -> case x of alts
It saves the writer using an explicit name which must be unique and the reader determining that the name is not used deeper in the expressions. (and a "->"). I tend to find myself wanting this after already having written a 'case' and decided I don't need/want a name for the thing being 'cased'. I wouldn't mind "case of", "\of" or "\case of", for using it.
Allowing multiple arguments - is syntactically difficult to reconcile with 'case' because it restricts what single-argument forms can be used? Such as:
case foo of Just n -> n is allowed but f Just n = n isn't.
Isaac _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (9)
-
Benjamin Franksen
-
Bertram Felgenhauer
-
Brandon Michael Moore
-
Brian Hulley
-
Dan Weston
-
Duncan Coutts
-
Isaac Dupree
-
Stefan O'Rear
-
Thomas Schilling