From: Caleb Clausen Date: 2009-08-25T02:28:40+09:00 Subject: [ruby-core:25099] Re: Proposal: Simpler block format Yehuda Katz wrote: > On Sun, Aug 23, 2009 at 2:00 PM, Caleb Clausen > 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.