http://www.perlmonks.org?node_id=944004


in reply to Re: Re^4: Closure on Closures (beta)
in thread Closure on Closures

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.

- tye