Yehuda Katz wrote:
> On Sun, Aug 23, 2009 at 2:00 PM, Caleb Clausen <caleb / inforadical.net 
> <mailto:caleb / inforadical.net>> wrote:
>     But I'd like to see a more explicit description of how this would
>     work, if I am to implement it. Making reference to an existing
>     parser implementation is unhelpful for me, especially as I am not
>     familiar with the internals of that implementation. Things that
>     cause parse errors for MRI may not for redparse; redparse is
>     generally looser and more tolerant than MRI parse.y. In other words,
>     what would the appropriate section of a ruby standard read when
>     describing this feature?
> 
> 
> Understood -- but you do have the implementation to refer to. I agree 
> that in order for this to be accepted, we would need to provide new 
> RubySpecs to specify the behavior. I believe ujihisa is working on that.

A spec is nice and all, but I guess what I'm really looking for is a 
description in english, not in code, of how this new syntax behaves. I 
think it is important to have this kind of description in order to think 
about it properly. I haven't been able to persuade you to come up with 
such a thing, so maybe I'll take a shot at it:

A proc literal can be written as an expression enclosed in curly braces 
({}). Since blocks and hash literals can also be enclosed in curlys, 
there are some rules for distinguishing proc literals from those other 
cases:

1) If the { immediately follows an identifier, method name, or method 
argument list enclosed in parens, then it is a block.

2) If the { is followed by a parameter list enclosed by goalposts (||), 
then it is a proc literal.

3) If the {...} contains a pair of expressions, separated by =>, then it 
is a hash literal. (Note that => does not create an expression; it isn't 
valid on it's own but only inside a larger context.)

4) If the {...} contains a new-style hash initialization pair, in the 
form identifier: expression, then it is a hash literal. (Again, the : 
does not create an expression.)

5) If the {...} contains a list of such => or : pairs, separated by 
commas, then it is a hash literal.

6) An empty pair of curlys is always considered an (empty) hash literal.

7) Otherwise, {...} is a proc literal.

8) Note that in this case:
   { p q => r }
the => is not available to the {...}, to convert it to a hash literal, 
because the => has already been "eaten" by p's method parameter list. On 
the other hand, in these cases:
   { p {} => r }
   { p () => r }
the => does get used as part of the hash literal, since p's parameter 
list ends before the =>. (This is all consonant with existing rules 
about how parens following a method name get parsed. So, 8) shouldn't be 
confusing to parsers, but is potentially to humans.)


I agree with Matz that confusing the humans is a bad thing; to that end, 
perhaps this new syntax should be modified slightly so that
   { p q => r }
remains a syntax error. Users should add parentheses to disambiguate 
that into either
   { p( q => r ) }
or
   { p(q) => r }

So humans can always employ the rule that an => inside curlys creates a 
hash.