On Sat Jul 07 18:35:03 2012, tom christiansen wrote:
> "Father Chrysostomos via RT" <[email protected]> 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 <[email protected]>
> To: Tom Christiansen <[email protected]>
> CC: Larry Wall <[email protected]>
> 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