From: Eric Mahurin Date: 2005-10-02T08:37:37+09:00 Subject: Re: ideas for an RCR: variable locality --- Bob Hutchison wrote: > On Oct 1, 2005, at 4:55 PM, Eric Mahurin wrote: > > 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. > > > > > > You need gensym as lisp has (and I had in a previous > example), in > which case you get this back on the last example, and there > is no > problem: > > (a_1=x;b_2=(a_3=y;b_4=z;a_3 b_2) Yes, something like this would work (using your Gensym module): min2 = lambda { |a,b| v1 = Gensym.gensym v2 = Gensym.gensym "(#{v1}=#{a};#{v2}=#{b};#{v1}<#{v2} ? #{v1} : #{v2})" } Here are the disadvantages of this compared to having ruby do local variables: - not as natural/uglier - clutters the namespace/variable table - prevents GC from freeing objects that these variables reference __________________________________ Yahoo! Mail - PC Magazine Editors' Choice 2005 http://mail.yahoo.com