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