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

Re: How much do we close over?

Thread Previous | Thread Next
From:
Piers Cawley
Date:
June 13, 2005 00:37
Subject:
Re: How much do we close over?
Message ID:
m23brmhfmt.fsf@obelisk.bofh.org.uk
Rod Adams <rod@rodadams.net> 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
>>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.

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:

    $continuation.bindings.eval_in_this_scope($^codestring);

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

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About