develooper Front page | perl.perl6.language | Postings from June 2005

Re: How much do we close over?

Thread Previous | Thread Next
Rod Adams
June 12, 2005 16:22
Re: How much do we close over?
Message ID:
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
>If it's not the default can it please be mandated that there be some way of
>    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

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About