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