Embrace closures

By 8 Vynce on March 13, 2007

{
my @teachers = ("Rob", "talby");

sub flux_educator {
my $t = shift @teachers;
push @teachers, $t;
return $t;
}
}

Embed Claim Make a related claim

Discussion (15)

http://www.tapsellferrier.co.uk/nicferrier/

8 nic who agreed, says

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.

http://www.tapsellferrier.co.uk/nicferrier/

8 nic who agreed, says

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.


def maker(x):
def moder(y):
return x * y
return moder

maker(10)(7)

Make a related claim 10 months ago (link)
http://vynce.myopenid.com/

8 Vynce who agreed, says

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.

Make a related claim 10 months ago (link)
http://www.tapsellferrier.co.uk/nicferrier/

8 nic who agreed, says

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.

Make a related claim 10 months ago (link)
http://vynce.myopenid.com/

8 Vynce who agreed, says

"collecting" the sub? what?

Make a related claim 10 months ago (link)
http://www.tapsellferrier.co.uk/nicferrier/

8 nic who agreed, says

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.

Make a related claim 10 months ago (link)
http://darch.myopenid.com/

6 D'Archangel who agreed, says

"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

Make a related claim 10 months ago (link)
http://www.tapsellferrier.co.uk/nicferrier/

8 nic who agreed, says

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.

Make a related claim 10 months ago (link)
http://vynce.myopenid.com/

8 Vynce who agreed, says

not in perl.

Make a related claim 10 months ago (link)
http://vynce.myopenid.com/

8 Vynce who agreed, says

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.

Make a related claim 10 months ago (link)
http://www.tapsellferrier.co.uk/nicferrier/

8 nic who agreed, says

So subroutines don't have scope in Perl? I never knew that!

Anonymous subs have scope though right?

Make a related claim 10 months ago (link)
http://darch.myopenid.com/

6 D'Archangel who agreed, says

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

Make a related claim 10 months ago (link)
http://vynce.myopenid.com/

8 Vynce who agreed, says

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.

Make a related claim 10 months ago (link)
http://darch.myopenid.com/

6 D'Archangel who agreed, says

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

Make a related claim 10 months ago (link)
http://www.tapsellferrier.co.uk/nicferrier/

8 nic who agreed, says

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.

Make a related claim 10 months ago (link)
Sign in in to leave a comment.