Being able to run code more than once using the same variable isn't enough to be "a closure".
a closure is a data structure that holds an expression and an environment of variable bindings in which that expression is to be evaluated.
There might be a data structure involved in the not-first iterations of the
{
my $foo = 99;
CODE: print ++$foo, "\n";
}
goto CODE;
example. But such a data structure is not evident and you can't call the example "a closure" (based on that definition and also IMHO). You could postulate that the example hints at a closure being use behind the scenes.
But I suspect that you might be hard pressed to find one data structure that contains the 'print' "expression" and the "environment" containing the second(?) instance of $foo or you'd have to define your one "data structure" as something that contains way more stuff than that.
The "named closure" examples are an edge case for me. I don't particularly mind people calling them a closure but I'm more likely to restrict my use of that word because I think a narrower definition of that word is usually more useful.
I call the "named closure" case "static (or 'state') variables that happen to be implemented using a closure". And it turns out that the closure in that case is stored in the symbol table and when that storing happens is actually important.
for( 2,3,5,7 ) {
my $x= my $y= $_;
sub pow {
return $y *= $x;
}
}
print pow(), $/ for 1..3;
__END__
4
8
16
Unfortunately, Perl isn't (currently) smart enough to warn about that case, but it will warn about this equivalent:
sub wow {
my $x= my $y= shift @_;
sub pow {
return $y *= $x;
}
}
wow($_) for 2, 3, 5;
print pow(), $/ for 1..3;
__END__
Variable "$y" will not stay shared at - line 4.
Variable "$x" will not stay shared at - line 4.
4
8
16
A closure is generated when that code is compiled. And that closure is stored in *{$main::{pow}}{CODE}. When new instances of $x and $y are created, no new closures are created.
So I usually only talk about closures when I'm talking about the reference to the code (the reference that also contains references to some closed-over variable instances). If the reference isn't evident, then "closure" or not usually is an implementation detail.
|