On Sat Jul 07 22:23:16 2012, thoughtstream wrote:
> 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.

I said when, not whether. :-)

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

Thank you.

Does Perl 6 have an equivalent to this?

    my $x;
    for $x(1..10) {}

In this case, the loop reuses the $x slot in the pad, making the
existing $x name an alias to a different scalar.  But, due to the way
Perl 5 closures work, it is, for all tents and porpoises, the same as this:

    my $x;
    for my $x(1..10) {}

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

Except that my sub foo happens upon block entry, right?

> 
> HTH,

It does, but I am still trying to wrap my head around the fundamental
difference between 5 and 6 with regard to closures.

In Perl 5, $] in a piece of code is bound to *], not $], so it sees
changes made by local($]) (which actually puts a completely new scalar
in the *]{SCALAR} slot).  But ‘my $x; sub { $x }’ is bound, not to the
$x slot in the outer block/sub/file, but to the actual scalar itself.

It seems that Perl 6 closures close over the slot, not the
scalar/array/etc.  Is that right?

Anyway, I think I know how to implement this now.

The first time a ‘my’ sub is referenced or called, it is cloned.  The
clone is stored for reuse, but that storage is localised to the current
block.

-- 

Father Chrysostomos

Reply via email to