Re: When do named subs bind to their variables? (Re: Questionable scope of state variables ([perl #113930] Lexical subs))
On Sat Jul 07 18:35:03 2012, tom christiansen wrote: > "Father Chrysostomos via RT" wrote >on Sat, 07 Jul 2012 17:44:46 PDT: > > > I’m forwarding this to the Perl 6 language list, so see if I can > find > > an answer there. > > I do have an answer from Damian, which I will enclose below, and a > Rakudo result for you. > > > [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.] > > [...] > > > 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(); > > } > > The answer to your immediate question is that if you call foo(), > it prints out 456 under Rakudo. Thank you. So the bar sub seems to be closing over the name @a (the container/variable slot/pad entry/whatever), rather than the actual array itself. Since I don’t have it installed, could you tell me what this does? sub foo { my @a = (1,2,3); my sub bar { say @a }; bar(); @a := [4,5,6]; bar(); } foo(); And this? sub foo { my @a = (1,2,3); bar(); @a := [4,5,6]; bar(); my sub bar { say @a }; } foo(); And this? sub foo { my @a = (1,2,3); my sub bar { say @a }; my $bar = &bar; $bar(); # is this syntax right? @a := [4,5,6]; $bar(); } foo(); > > Following is Damian's answer to my question, shared with permission. > > --tom > > From: Damian Conway > To:Tom Christiansen > CC:Larry Wall > Date: Sun, 08 Jul 2012 07:17:19 +1000 > Delivery-Date: Sat, 07 Jul 2012 15:19:09 > Subject: Re: my subs and state vars > In-Reply-To: <22255.1341691089@chthon> > > X-Spam-Status: No, score=-102.6 required=4.5 > tests=BAYES_00,RCVD_IN_DNSWL_LOW, >USER_IN_WHITELIST autolearn=ham version=3.3.0 > > X-Google-Sender-Auth: UHLwfgo2kyvv2prdl6qJm-RfLF8 > Content-Type: text/plain; charset=ISO-8859-1 > > > It looks like perl5 may be close to having my subs, but a puzzle > > has emerged about how in some circumstances to treat state > > variables within those. [I'm pretty sure that perl6 has > thought > > this through thoroughly, but [I] am personally unfamiliar with > the > > outcome of said contemplations.] > > > > I bet you aren't, though. Any ideas or clues? > > The right things to do (and what Rakudo actually does) is to treat > lexical subs as lexically scoped *instances* of the specified sub > within the current surrounding block. > > That is: a lexical sub is like a "my" var, in that you get a new > one > each time the surrounding block is executed. Rather than like an > "our" > variable, where you get a new lexically scoped alias to the same > package > scoped variable. > > By that reasoning, state vars inside a my sub must belong to each > instance of the sub, just as state vars inside anonymous subs > belong to > each instance of the anonymous sub. > > Another way of thinking about what Perl 6 does is that: > > my sub foo { whatever() } > > is just syntactic sugar for: > > my &foo := sub { whatever() } Does that mean I cannot call it before it is declared? > That is: create a lexically scoped Code object and alias it at > run-time > to an anonymous subroutine. So the rules for state variables > inside > lexical subs *must* be the same as the rules for state variables > inside > anonymous subs, since they're actually just two ways of creating > the > same thing. I see. > > With this approach, in Perl 6 it's easy to specify exactly what > you want: > > sub recount_from ($n) { > > my sub counter { > state $count = $n; # Each instance of &counter has > its own count > say $count--; > die if $count == 0; > } > > while prompt "recount $n> " { > counter; > } > } > > vs: > > sub first_count_down_from ($n) { > > state $count = $n; # All instances of &counter share > a common count > > my sub counter { > say $count--; > die if $count == 0; > } > > while prompt "first count $n> " { > counter; > } > } > > Feel free to forward the above to anyone who might find it useful. What I am really trying to find out is when the subroutine is actually cloned, and whether there can be multiple clones within a single call of the enclosing sub. -- Father Chrysostomos
Re: When do named subs bind to their variables? (Re: Questionable scope of state variables ([perl #113930] Lexical subs))
Father Chrysostomos asked: > What I am really trying to find out is when the subroutine is actually > cloned, Yes. It is supposed to be (or at least must *appear* to be), and currently is (or appears to be) in Rakudo. > and whether there can be multiple clones within a single call of > the enclosing sub. Yes. For example, a lexical sub might be declared in a loop inside the enclosing sub, in which case it should produce multiple instances, one per iteration. For example, this: sub outer_sub () { for (1..3) { state $call_num = 1; my sub inner_sub { state $inner_state = (1..100).pick; # i.e. random number say "[call {$call_num++}] \$inner_state = $inner_state"; } say "\nsub id: ", &inner_sub.id; inner_sub(); inner_sub(); } } outer_sub(); produces: sub id: -4628941774842748435 [call 1] $inner_state = 89 [call 2] $inner_state = 89 sub id: -4628941774848253711 [call 3] $inner_state = 16 [call 4] $inner_state = 16 sub id: -4628941774839825925 [call 5] $inner_state = 26 [call 6] $inner_state = 26 under Rakudo BTW, Both the above "yes" answers are consistent with (and can be inferred from) the previous explanation that: my sub foo { whatever() } is just a syntactic convenience for: my &foo := sub { whatever() } HTH, Damian
Re: When do named subs bind to their variables? (Re: Questionable scope of state variables ([perl #113930] Lexical subs))
"Father Chrysostomos via RT" wrote on Sat, 07 Jul 2012 18:54:15 PDT: >Thank you. So the bar sub seems to be closing over the name @a (the >container/variable slot/pad entry/whatever), rather than the actual >array itself. >Since I don't have it installed, could you tell me what this does? All three of those say the same thing: 123 456 --tom
Re: When do named subs bind to their variables? (Re: Questionable scope of state variables ([perl #113930] Lexical subs))
"Father Chrysostomos via RT" wrote on Sat, 07 Jul 2012 17:44:46 PDT: > I’m forwarding this to the Perl 6 language list, so see if I can find > an answer there. I do have an answer from Damian, which I will enclose below, and a Rakudo result for you. > [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.] [...] > 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(); > } The answer to your immediate question is that if you call foo(), it prints out 456 under Rakudo. Following is Damian's answer to my question, shared with permission. --tom From: Damian Conway To:Tom Christiansen CC:Larry Wall Date: Sun, 08 Jul 2012 07:17:19 +1000 Delivery-Date: Sat, 07 Jul 2012 15:19:09 Subject: Re: my subs and state vars In-Reply-To: <22255.1341691089@chthon> X-Spam-Status: No, score=-102.6 required=4.5 tests=BAYES_00,RCVD_IN_DNSWL_LOW, USER_IN_WHITELIST autolearn=ham version=3.3.0 X-Google-Sender-Auth: UHLwfgo2kyvv2prdl6qJm-RfLF8 Content-Type: text/plain; charset=ISO-8859-1 > It looks like perl5 may be close to having my subs, but a puzzle > has emerged about how in some circumstances to treat state > variables within those. [I'm pretty sure that perl6 has thought > this through thoroughly, but [I] am personally unfamiliar with the > outcome of said contemplations.] > > I bet you aren't, though. Any ideas or clues? The right things to do (and what Rakudo actually does) is to treat lexical subs as lexically scoped *instances* of the specified sub within the current surrounding block. That is: a lexical sub is like a "my" var, in that you get a new one each time the surrounding block is executed. Rather than like an "our" variable, where you get a new lexically scoped alias to the same package scoped variable. By that reasoning, state vars inside a my sub must belong to each instance of the sub, just as state vars inside anonymous subs belong to each instance of the anonymous sub. Another way of thinking about what Perl 6 does is that: my sub foo { whatever() } is just syntactic sugar for: my &foo := sub { whatever() } That is: create a lexically scoped Code object and alias it at run-time to an anonymous subroutine. So the rules for state variables inside lexical subs *must* be the same as the rules for state variables inside anonymous subs, since they're actually just two ways of creating the same thing. With this approach, in Perl 6 it's easy to specify exactly what you want: sub recount_from ($n) { my sub counter { state $count = $n; # Each instance of &counter has its own count say $count--; die if $count == 0; } while prompt "recount $n> " { counter; } } vs: sub first_count_down_from ($n) { state $count = $n; # All instances of &counter share a common count my sub counter { say $count--; die if $count == 0; } while prompt "first count $n> " { counter; } } Feel free to forward the above to anyone who might find it useful. Damian