On Mon, Apr 25, 2005 at 02:13:26AM +0800, Autrijus Tang wrote: : A while ago I posted a conflict between a block containing a pair : constructor, vs. a hash constructor: : : map { $_ => $_ } @foo; : : Larry suggested that to keep it from being collapsed, we somehow : augment toplevel AST: : : map { $_ => $_; } @foo; : map { +($_ => $_) } @foo;
Uh, I'm not sure what + would return for a Pair, but I'm pretty sure it's not a pair. A little P5ism sneaking in there? :-) : But here is a new idea: Since the parser knows that the bare block is : followed by no trailing comma, how about we using it as a disambiguating : device, and define that it never collapses? : : map { $_ => $_ } @foo; # closure : map { $_ => $_ }, @foo; # hash A block can be arbitrarily long. I worry about disambiguating it by something could come lines later. It's the /x problem all over again. Plus, I think many folks would rather think of the closure comma as optional rather than mandatorily missing. Besides, if they can't keep the {...} straight, they're not gonna keep the comma straight either. : And maybe it can be extended over adverbial blocks, too: : : @foo.map:{ $_ => $_ }; # closure : : Also as control structure body, just for consistency's sake: : : for @foo { $^x => $^y }; : : Is it a sane approach? I have just tentatively implemented it as r2305 : if people would like to experiment with this proposal. I really think for clarity it has to be disambiguated by either something syntactic on the front or something semantic at the top level. It's probably pretty easy to catch the error of saying map { $_ => $_ } @foo; when you mean map { hash $_ => $_ } @foo; or map { list $_ => $_ } @foo; because map wants a closure as its first argument, not a hash. I still kinda like the rule that it's a hash if the top-level looks like some kind of list of pairs. It optimizes for the common case. Closures returning pairs are a rarity. Larry