Piers Cawley wrote:

Chip and I have been having a discussion. I want to write:

   sub foo { my $x = 1; return sub { eval $^codestring } }
   say foo()("$x");

I claim that that should print 1. Chip claims it should throw a warning about
because of timely destruction. My claim is that a closure should close over the
entire lexical stack, and not simply those things it uses statically. Chip
claims the opposite, arguing that timely destruction implies that this is
absolutely the right thing to do. It's also quicker.
I'm going to have to side with Piers on this one. My feeling is that having a reference to a closure accessible in memory should keep all the possible lexicals it can access in memory as well. That said, I can the compiler optimizing memory consumption by destroying all the outer lexicals that it can prove will never be used by the inner closure. However, the presence of an 'eval' in the closure makes such a proof tenuous at best.

On the other hand, one could easily view the eval as constructing yet another closure, and it's unclear if we wish for that closure to be able to "skip" the first level outer closure to directly access the 2nd level outer lexicals. In that respect, I could see things Chip's way.

As for the warning, it should only be a warning if strictures are on, for using the now undeclared '$x' inside the eval.

But dammit, I'm doing runtime evaluation of code strings, I don't care about
quicker.

If it's not the default can it please be mandated that there be some way of
doing:

   sub foo { my $x = 1; return sub is lexically_greedy {eval $^codestring} }

in other words, some way of declaring that a subroutine wants to hang onto
every lexical it can see in its lexical stack, not matter what static analysis
may say.

Well, you could always do something like:

sub foo { my $x = 1; return sub {my $x := $OUTER::x; eval $^codestring} }

But I'm spending too much time in other languages lately to remember exactly how "$OUTER::x" is spelled for certain. One could probably even write a macro that auto-binds all the lexicals in the outer scope to the current scope.

-- Rod Adams

Reply via email to