And closures lead to continuations passing style. They're so cool.
Incidentally, despite rumours to the contrary there aren't many languages you can't do closures with. GNU C even provides support for them which I will claim separately.
hm. in perl, what i wrote is called a closure. from outside the block given, @teachers is unknown and can't be futzed with, but flux_educator() will alternate return values.
You declare a scope in which you declare the variable @teachers and the subroutine flux_educator. The variable @teachers is referenced by the subroutine.
But it's not a closure until the original lexical block is out of scope. In other words if you return the subroutine to another call outside that scope then it's closure.
"But it's not a closure until the original lexical block is out of scope."
That's just not so. The closure happens as soon as we have persistent state associated with a particular function. Whether the function is named or anonymous is irrelevant.
Err... that wasn't my point. If the function is named or anonymous isn't anything to do with it. Vynce's sub would simply be GC'd along with the lexical scope it closed.
to clarify, if you add "print flux_educators; print flux_educators" after the code i have written (meaning, outside the outermost curlies) it fidn the subroutine and do the thing. try it.
it was not until your confusion that I realized that might be construed as inconsistent handling of namespace; i just don't expect the rules to be the same for the subroutine as for the variable.
D'Archangel has the right of it. subs are package scoped, the 'my' variable is block scoped. anonymous subs are generally either consumed immediately or assigned into a variable (e.g. scalar coderef), in which case they are (i suppose) variable scoped and that variable's scope is whatever you say it is -- use my and it's block-scoped, use our and it's global, etc.
The point I was trying to get to (rather abstrusely) by talking about the difference between anonymous and named functions is that while anonymity -- i.e., the ability to have multiple copies of the same closure -- is much of what gives closures their power, it is not a condition of closure. All you need for that is a function that is tied to an environment, which Vynce's code sample provides.
This also contains a closure:
------
sub makeCounter {
my ($x) = 0;
return sub {
return $x++;
}
}
------
And it has the benefit that you can have as many of these as you would like. But it's no more a closure than Vynce's example.
Yes. I see your point. It's quite right I think. The problem I was seeing was because I didn't realize named subs were different from anonymous subs in Perl.
That's a nit about Perl's lexical scoping rules I guess. It's not "normal" for lexical scope to behave that way.
Discussion (15)
And closures lead to continuations passing style. They're so cool.
Incidentally, despite rumours to the contrary there aren't many languages you can't do closures with. GNU C even provides support for them which I will claim separately.
Claims inspired by this comment
GCC let's you do closures with CJava supports closures (kinda)
Postgresql plpgsql supports yielding (or constrained continuations)
Javascript provides closures
Now I look at this again I see it's not really a closure.
The point about closures is the capturing of higher scope even after the higher scope is no longer lexically relevant.
So this is a better example, in python.
hm. in perl, what i wrote is called a closure. from outside the block given, @teachers is unknown and can't be futzed with, but flux_educator() will alternate return values.
Right... it's not immediately obvious from your example that flux_educator is a return value.
It is of course, as long as something is collecting the sub somehow.
"collecting" the sub? what?
You declare a scope in which you declare the variable @teachers and the subroutine flux_educator. The variable @teachers is referenced by the subroutine.
But it's not a closure until the original lexical block is out of scope. In other words if you return the subroutine to another call outside that scope then it's closure.
"But it's not a closure until the original lexical block is out of scope."
That's just not so. The closure happens as soon as we have persistent state associated with a particular function. Whether the function is named or anonymous is irrelevant.
D'A
Err... that wasn't my point. If the function is named or anonymous isn't anything to do with it. Vynce's sub would simply be GC'd along with the lexical scope it closed.
not in perl.
to clarify, if you add "print flux_educators; print flux_educators" after the code i have written (meaning, outside the outermost curlies) it fidn the subroutine and do the thing. try it.
it was not until your confusion that I realized that might be construed as inconsistent handling of namespace; i just don't expect the rules to be the same for the subroutine as for the variable.
So subroutines don't have scope in Perl? I never knew that!
Anonymous subs have scope though right?
I think it is more correct to say that the "my" specifically limits the variable to closure scope while the subroutine winds up in package scope.
I think. My brain is a little broken today.
D'A
D'Archangel has the right of it. subs are package scoped, the 'my' variable is block scoped. anonymous subs are generally either consumed immediately or assigned into a variable (e.g. scalar coderef), in which case they are (i suppose) variable scoped and that variable's scope is whatever you say it is -- use my and it's block-scoped, use our and it's global, etc.
The point I was trying to get to (rather abstrusely) by talking about the difference between anonymous and named functions is that while anonymity -- i.e., the ability to have multiple copies of the same closure -- is much of what gives closures their power, it is not a condition of closure. All you need for that is a function that is tied to an environment, which Vynce's code sample provides.
This also contains a closure:
------
sub makeCounter {
my ($x) = 0;
return sub {
return $x++;
}
}
------
And it has the benefit that you can have as many of these as you would like. But it's no more a closure than Vynce's example.
Again, I think.
D'A
Yes. I see your point. It's quite right I think. The problem I was seeing was because I didn't realize named subs were different from anonymous subs in Perl.
That's a nit about Perl's lexical scoping rules I guess. It's not "normal" for lexical scope to behave that way.