"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.

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() }

    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

Reply via email to