From: Phil Tomson Date: 2005-10-14T05:31:55+09:00 Subject: Re: Default argument values for blocks Eric Mahurin wrote: > --- Austin Ziegler wrote: > > > On 10/13/05, Phil Tomson wrote: > > > While I tend to agree that there are probably much better > > parser > > > generators available now like ANTLR or even using a > > Ruby-based one like > > > Rockit, I can understand the hesitation to change from > > yacc. It's a > > > huge amount of work for one, and there would need to be a > > lot of > > > testing to ensure that nothing has broke. I suspect that a > > change from > > > yacc to another parser generator would delay Ruby2.0 by at > > least > > > several months. Maybe that would be OK. Perhaps there > > would be other > > > advantages gained by moving away from yacc that would help > > justify > > > doing so? > > > > > > I'm still in the "It might be a nice feature to have, but > > it's not > > > really needed enough to justify the kinds of changes being > > suggested" > > > category. > > > > I'm suggesting that it may be time for a parser change > > because the > > proposed language changes IMO are really really really ugly > > -- and I'd > > rather see: > > > > foo = lambda { |foo = 1 | 2| puts foo } > > > > work than not. > > How do you interpret the above? > > foo = lambda { |foo = 1| (2|puts foo) } > > or > > foo = lambda { |foo = (1|2)| puts foo } > > I think the first interpretation is implementable in most > parsers (including yacc, I think) relatively easily if you just > don't allow "|" directly in the default value (unlike a normal > RHS). The second interpretation would be more difficult > because it would require an arbitrary amount of lookahead. > Even if the parser can do it, I think arbitrary amounts of > lookahead should be avoided in a language because it will > result in a performance hit (like backtracking in regular > expressions). > > I'm not a parser expert, but wouldn't the second example you pose be helped by the fact that you've enclosed the '1|2' expression in parens? wouldn't that expression within the parens be evaluated first and the resulting value substituted into the 'foo = ' expression? I ask because a lot of people have suggested that requiring enclosing bitwise OR expressions in parens in the block param would solve the problem. I don't see any way to do the following without lookahead: foo = lambda { |foo = 1|2|3| puts foo } And as you say the more lookahead you're doing, the slower the parser will be. The goalposts are problematic for this sort of thing. What about an alternative (some have been suggested): lambda{ (foo = 1|2) puts foo } If that one is problematic, then maybe: lambda{ |(foo = 1|2, bar = foo|3)| puts foo, bar } This one was proposed long ago as a way to declare a var whose scope is outside the block: lambda { puts foo } But again, I think we should hold out for the 'ideal' syntax or just forget about the proposed feature. Phil