From: ES Date: 2005-10-02T07:27:27+09:00 Subject: Re: ideas for an RCR: variable locality Eric Mahurin wrote: > --- ES wrote: > > >>Eric Mahurin wrote: >> >>>I would like to start this thread with end goal being to >> >>create >> >>>an RCR to control variable locality in the language (or >>>determine that there is already a reasonable alternative). >>> >>>Problem: Within a method you can't reuse a variable name >> >>for a >> >>>local variable. Some changes in ruby 2 may help the issue, >> >>but >> >>>also hurt it in another way. >>> >>>Example: For performance reasons, I'm having my package >>>(grammar - generic parser), generate flattened (reduce >>>calls/stack depth) code. As long as each "method" (to be >>>flattened) is simple enough that it doesn't require local >>>variables I'm OK. But as soon one of these need a local >>>variable, I'm in trouble - that variable could step on the >> >>toes >> >>>of another including one just like it that it >> >>calls/flattens. >> >>Could you perhaps offer a reduced code example? Your problem >>description makes no sense (though probably due to fault of >>mine). > > > Here's one - a poor man's macro facility. Let's say a macro is > just a lambda that returns a string. You just eval it when you > need to execute the code for that macro. > > plus = lambda { |a,b| "(#{a}+#{b})" } > # will have to re-evaluate a or b if they are an expression > min1 = lambda { |a,b| "(#{a}<#{b} ? #{a} : #{b})" } > # use local variables to prevent re-evaluation > min2 = lambda { |a,b| "(a=#{a};b=#{b};a > # y+z may get evaluated twice > min1["x",plus["y","z"]] > # => "(x<(y+z) ? x : (y+z))" > > # y+z may evaluated once > min2["x",plus["y","z"]] > # => "(a=x;b=(y+z);a > # need to localize a/b for the inner min2 > min2["x",min2["y","z"]] > # => "(a=x;b=(a=y;b=z;a > > See the problem on this last example? We really need to > localize a and b. There isn't a good facility to do this. Well, I would have to say in that case the main problem is the design itself. However, I think I see the issue: you mean *block-local* variables, right, not regular local variables? As in, foo = 5 bar = lambda {|foo| foo += 1} # Should be a local foo, not the above? E