On Sat Jul 07 18:35:03 2012, tom christiansen wrote:
> "Father Chrysostomos via RT" <perlbug-comm...@perl.org> 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 <dam...@conway.org>
>     To:            Tom Christiansen <tchr...@perl.com>
>     CC:            Larry Wall <la...@wall.org>
>     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

Reply via email to