On Wednesday 09 July 2008 13:46:19 Bob Rogers wrote:

>    From: "Patrick R. Michaud" <[EMAIL PROTECTED]>
>    Date: Wed, 9 Jul 2008 08:25:52 -0500

>    If I understand what you're saying, and then take it to what I see
>    as its ultimate conclusion, you're basically claiming that every
>    call to a subroutine involving lexicals requires a newclosure op.
>
> Yes; I believe that's a cleaner design.  Doing otherwise relies on
> runtime heuristics to decide what context ought to have been closed
> over, which strikes me as much less reliable.  Of course, I don't *need*
> the cleaner design, since I can just ignore the runtime heuristics -- as
> long as they don't break the newclosure case.

I read that in the lexicals PDD, and I think the current behavior is bizarre 
*without* the call to newclosure.  How is it even possible to close over a 
lexical environment in an outer when that lexical environment was never even 
created?

It's difficult to describe that as anything other than ridiculous.

Consider Bob's example Perl 5 code:

        sub outer {
            my $x = shift;

            print "outer foo $x\n";

            sub inner {
                print "inner foo $x\n";
            }
        }

        # Note that it is not illegal to call inner before outer.
        inner();

There's a compile-time warning here, namely that $x will not stay shared.  
Even though it looks like inner() should close over outer()'s $x per Perl 5's 
scoping rules (ignoring that you can't nest subs in Perl 5), there is no $x 
available at the call to inner().

If you wrote this instead:

        sub outer {
                my $x = shift;

                print "outer foo $x\n";

                return sub {
                        print "inner foo $x\n";
                }
        }

        my $inner = outer( 10 );
        $inner->();

... then Perl 5 effectively performs a newclosure action, attaching the active 
lexpad to the new instance of the subroutine reference.

I suspect the motivation for the bizarreness of the specification is the 
desire to make code like this work in Parrot:

        {
                my $x;

                sub set_x { $x = shift }
                sub get_x { return $x }
        }

... except that there's no real way in Parrot right now to create an enclosing 
lexical block, activate it, and attach it as the outer to one or more 
Closures.

-- c

Reply via email to