Eric Mahurin wrote:
> --- ES <ruby-ml / magical-cat.org> wrote:
> 
> 
>>Eric Mahurin wrote:
>>
>>>--- ES <ruby-ml / magical-cat.org> 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<b ? a : b)" }
>>>
>>># 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<b ? a : b)"
>>>
>>># need to localize a/b for the inner min2
>>>min2["x",min2["y","z"]]
>>># => "(a=x;b=(a=y;b=z;a<b ? a : b);a<b ? a : b)"
>>>
>>>
>>>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.
> 
> 
> I just wanted to give a simple example where having some kind
> of local variable facility would easily solve the problem.  In
> many other cases, you can simply choose an unused name to solve
> the problem (the case you have below).
> 
> 
>>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?
> 
> 
> This particular issue should be fixed in Ruby 2 from my
> understanding - block arguments will ALWAYS be local.  I'm
> really talking about localizing other variables in a block and
> localizing variables in something like a begin/end block.
> 
> So, in the example above, my module/end proposal would look
> something like this:
> 
> min2  = lambda { |a,b| "module;a=#{a};b=#{b};a<b ? a : b;end" }
> 
> min2["x",min2["y","z"]]
> # => "module;a=x;b=module;a=y;b=z;a<b ? a : b;end;a<b ? a :
> b;end"
> 
> Again, my module/end proposal would localize all variables
> inside, but would use an external value when reading a local
> variable not yet defined.  I proposed to reuse "module" to not
> create a new keyword, but something else could be used.
> 
> And on the block side, I proposed a new block format ({{...}})
> which would do the same for variables inside the block.  In
> ruby 2, the default block will have all variables scoped at the
> same as what contains the block.

Ah.. er.

Some kind of automatic name mangling to avoid binding?

I mean, I just do not see where this would cause any problems apart
from when one is defining a block locally in which case one should
take care not to trample on the local namespace anyway. Typically
being able to access the enclosing scope is much more valuable.

This seems like a very special-use-case and would probably just
warrant a library of some sort at most.


E
--
No-one expects the Solaris POSIX implementation!