jastrachan | 8 Mar 14:39 2005

Re: Closure syntax


I think -> looks funny on a fair amount of screens / terminals and that 
=> is visually a little to close to the other comparisons we have (>= 
<= <=> =~) so I'm thinking :: seems to be the simplest and closest to 
the classic | visually

collection.each {e:: println e}

Its also a little less noisy than the double bar

collection.each {|e| println e}

Unless anyone can think of any big reason not to use :: (so far we've 
managed fine without using it for name/package/module resolution) I'm 
thinking its the simplest change which looks fairly similar visually to 
our classic use of | but allows completely unambiguous & simple closure 
grammar rules. Its a little bit of a shame to be turning our backs from 
our math/smalltalk/ruby | notation, but | is a little too ambiguous 
when we fully support closure parameter lists as complex & powerful as 
in the rest of Groovy.

Its worth saying that the use of | does work for > 90% of cases in 
Groovy; people often omit the parameter list, its quite rare to use 
default arguments, especially with a binary or expression and so forth 
- however I'm not a huge fan of the {(args)| ... } syntax either; and 
I'd like us to have as few grammar rules with 'ifs' in as possible. 
e.g. rather than 'use | to separate closure parameters from the body, 
unless you're using a default parameter value on a parameter in which 
case...' I'd much prefer just 'use :: to separate closure parameters 
from the body'

I confess to being quite concerned about breaking backwards 
compatibility; and I've worried about this for a few days - however 
this is our one chance to simplify the grammar rules - as Guillaume 
said, we've already broken some backwards compatibility with classic 
Groovy and I think we should go for the :: change.

The thing which convinced me was that new users who are Java developers 
and come to Groovy for the first time will read the expressions

{x| foo.bar()}

as possibly being bitwise or and there is the potential for confusion. 
However by using a new separator token which is not used in Java we can 
avoid that confusion & help prompt the new Groovy developer to check 
out the language guide to see what :: means...

{x:: foo.bar()}

i.e. the :: alternative will not surprise users into thinking of 
existing Java syntax.

Are other folks happy with the use of :: or is there any strong views 
against it in favour of another token like -> or =>?

On 8 Mar 2005, at 10:58, John Rose wrote:
> On Mar 8, 2005, at 1:18, Jeremy Rayner wrote:
>> How about a keyword instead of a symbol...
> IMO, not so nice, since the rest of the closure syntax is punctuation 
> (left and right curly).
> Maybe it's just me, but in {x SEP y} I think the SEP wants to be 
> punctuation also.
> It sort of feels like  (X ? Y else Z) or (X do Y : Z) instead of (X ? 
> Y : Z).
> A keyword belongs before the curly brace, as Mike Spille and others 
> have advocated.
> This looks better because our eyes expect WORD (ARGS) { BODY } as a 
> theme in Java.
> However, that's not right for Groovy, since closures are as ubiquitous 
> in Groovy as blocks are in Java.
> (So much so, that the Java-compatible blocks in Groovy could be 
> defined as a special kind of closure.)
> Therefore, the first token of a closure should be left curly, and the 
> parameters optionally inserted.
> This decision lets Groovy preserve and amplify the theme of WORD 
> (ARGS) { BODY }, expanding
> it on occasion to EXPR (ARGS) { BODY }, WORD (ARGS) { VARS :: BODY }, 
> etc.
> -- John