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

Re: How much do we close over?

Thread Previous | Thread Next
Piers Cawley
June 13, 2005 00:37
Re: How much do we close over?
Message ID:
Rod Adams <> writes:

> 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.

Only if I actually know what variables which were within scope when that inner
sub was compiled are going to be used by my passed in code string. I really
don't want to have to write a macro to walk the OUTER:: chain in order to build
a something like:

   sub { my $foo = $OUTER::foo;
         my $bar = $OUTER::OUTER::bar;
         eval $^codestring }

Just to pull everything into scope.

And even if I could do that, what I actually want to be able to do is something
like this:


Which can be done today in Ruby and which is one of the enabling technologies
for tools like Rails.

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