I expect Perl 6 will have some way to define its variables as being
lexical-scoped in the sub they are used as default, either by the language
default, or by a pragma, as `use scope "subs"; ', as it's proposed in RFC
64.

If that's the case, I wonder how closures will be done, since having
lexical-scope in every sub would mean that variables inside closures would
automatically be lexical, being different from the ones in the sub that made
the closure.

    sub foo {
        $bar = 1;
        $closure = sub {
            return $bar++;
        };
        return $closure;
    }

The problem is that $bar inside the closure is different of the one in
`foo', because it's lexically scoped to the sub it's in, which is the
closure. The code above would actually compile to

    sub foo {
        my $bar = 1;
        my $closure = sub {
            my $bar;
            return $bar++;
        };
        return $closure;
    }

One naive way to solve this would be saying `only named subs will define a
lexical-scope for its variables', but that isn't right if you consider that
anonymous subs can be named, as

    *foo = sub {
        $bar = 1;   # not lexically scoped???
        ...

Of course typeglobs will probably go away, but I doubt naming an anonymous
sub will be cut of the language, since it's used by many modules that build
classes (Class::*, I'm not sure which of them do it... Someone can give some
examples?).


Well, my suggestion for solving the problem is creating a new keyword of the
my/our/your/their/his/... family that would explicitly `import' the variable
from the parent sub. Of course this would be a compile time thing (e.g. like
my), so that it would only tell the compiler that it should do the right
thing to that name access the parent sub's variable.

    sub foo {
        $bar = 1;
        $closure = sub {
            parent_sub's $bar;
            return $bar++;
        };
        return $closure;
    }

Of course `parent_sub's' sucks! But I have no better idea. Any suggestions?

I see a slightly conceptual advantage in having a keyword to indicate the
closure, because the variable is actually stored together with the sub
reference somehow, and having a keyword to indicate that would make it
explicit.


References:
* see the way Python does it, it's explicit but it's rather clumsy. In
Python, you must declare a parameter variable with some name, and set its
initial value as the outer variable's value. It kind of does the same thing
that this above, but uses initialised parameters to do this, what is rather
confusing.

In http://www.python.org/doc/current/ref/function.html :
>   # Return a function that returns its argument incremented by 'n'
>   def make_incrementer(n):
>       def increment(x, n=n):
>           return x+n
>       return increment
>
>   add1 = make_incrementer(1)
>   print add1(3)  # This prints '4'

Perl 5 would be:

    sub make_incrementer {
        my $n = shift;
        my $increment = sub {
            my $x = shift;
            return $x + $n;
        };
        return $increment;
    }

Perl 6 with parent_sub's (please give me a better name!) and
lexically-scoped variables by default:

    use scope 'subs';
    sub make_incrementer {
        $n = shift;
        $increment = sub {
            $x = shift;
            parent_sub's $x;
            return $x + $n;
        };
        return $increment;
    }



Comments?

- Branden

Reply via email to