I’m forwarding this to the Perl 6 language list, so see if I can find an
answer there.

[This conversation is about how lexical subs should be implemented in
Perl 5.  What Perl 6 does may help in determining how to iron out the
edge cases.]

On Sat Jul 07 13:23:17 2012, sprout wrote:
> On Sat Jul 07 12:53:32 2012, tom christiansen wrote:
> > Are you worried about this situation?
> > 
> >     sub outer {
> >         my @subs;
> >         for $i (1 .. 10) {
> >             my sub inner {
> >                 state $x = rand();
> >                 return [ $i => $x ];
> >             }
> >             push @subs, \&inner;
> >         }
> >         return @subs;
> >     }
> > 
> > The important question here is whether all those $x variables have
> > the same random number, or whether they have different ones.
> > 
> > And no, I don't know what the right answer is.  I do agree that
> > is the right question, though. :)
> 
> I think I have the right answer now.  If we document that only
> *anonymous* subroutines get their own copies of state variables when
> cloned, then my subs (personal subs? idiotic subs?) share them.
> 
> In the example you gave, those $x variables would all have the same
> random number.
> 
> If whether \&inner will clone the sub or not is supposed to be a matter
> of optimisation, that’s the only way it can work.
...
> > And later on there is this, which is interesting but not completely
> > revealing, since it deals with a my not a state:
> > 
> >     Lexical names do not share this problem, since the symbol goes out
> > of
> >     scope synchronously with its usage. Unlike global subs, they do
> > not need a
> >     compile-time binding, but like global subs, they perform a binding
> > to the
> >     lexical symbol at clone time (again, conceptually at the entry to
> > the
> >     outer lexical scope, but possibly deferred.)
> > 
> >         sub foo {
> >             # conceptual cloning happens to both blocks below
> >             my $x = 1;
> >             my sub bar { print $x }         # already conceptually
> > cloned, but can be lazily deferred
> >             my &baz := { bar(); print $x }; # block is cloned
> > immediately, forcing cloning of bar
> >             my $code = &bar;                # this would also force
> > bar to be cloned
> >             return &baz;
> >         }
> 
> That is interesting, since it is very similar to what I came up with on
> my own.
> 
> If a sub is conceptually cloned when the block enters, does that mean
> that my $code = &bar (\&bar in p5) twice in a row should produce the
> same value?
> 
> How does Perl 6 deal with my subs in for loops?

This question might be more appropriate:  In this example, which @a does
the bar subroutine see (in Perl 6)?

    sub foo {
        my @a = (1,2,3);
        my sub bar { say @a };
        @a := [4,5,6];
        bar();
    }

-- 

Father Chrysostomos

Reply via email to