Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Matts (1087)

Matts
  (email not shown publicly)

I work for MessageLabs [messagelabs.com] in Toronto, ON, Canada. I write spam filters, MTA software, high performance network software, string matching algorithms, and other cool stuff mostly in Perl and C.

Journal of Matts (1087)

Monday August 05, 2002
09:22 AM

What's a Closure?

[ #6903 ]

I talked a little bit about closures in my Exceptions talk at OSCon, taking my description from Damian's excellent book:

"In Perl, a closure is just a subroutine that refers to one or more lexical variables declared outside the subroutine itself"

Simple enough definition, right?

Well one thing I got to thinking about is file scope. Does this definition of closure extend to file scope?

e.g. instead of:

{
  my $x = 0;
 
  sub foo { print $x++ }
}
foo(); foo();

we can have:

# begin file
package Foo;
 
my $x = 0;
 
sub foo { print $x++ }
__END__

.. and in a separate file:

require "file1.pl";
Foo::foo(); Foo::foo();

This appears to have the same effect - the lexical variable $x is outside of the scope when we call the function, yet that function still has access to the variable, even though that scope has "finished".

However I brought this up on #london.pm and two perl programmers I respect most highly completely disagreed with me that these are closures. And maybe they are right in that they're not implemented internally as closures, but I think they act like closures, and look like closures, so for me it's easy enough to think of them as closures.

Where was I going with all of this?

Well what I'd like to do is look into the adding some sort of "proper" class semantics to perl 5. Yes I know I should wait for Perl 6, blah blah blah, but I have reasons for doing this so don't try and persuade me not to (mostly its that I want to stop being the annoying person on p5p who has something to say about everything - the guy from MJD's presentation who ruins everyones ideas (most recently regarding YAML - I wish I'd kept my mouth shut), but who has never actually contributed to perl's core - so I want to get to know the guts and see what doing this would take).

Here's how I expect a class to look under my scheme:

class Foo;
 
# I'm not hot on the "invar" keyword, but it's only syntax ;-)
invar $x;
invar $y;
 
sub set_x {
  my ($param) = shift;
  $x = $param;
}
 
sub get_x {
  $x;
}

The idea being that $x and $y there would be "instance variables". Now really this requires a totally new variable type in perl (as far as I can tell - otherwise you have to do it with source filters, and thats not the aim here - I'm looking for OO done right, not stuck on with sticky tape). So we already have my and our variables (lexicals and package vars) but we also need instance variables.

So tying these two together - the problem with lexical vars is they become closures, and I don't want one copy of the variable being tied into the sub - I want each invocation of that sub to get the right instance variable when it is called. The problem with package variables is similar - you get one instance of them. To do this right it needs to plug deep into the perl internals, and probably gets pretty scary. Hence the desire for a new type of variable.

Anyway... signing off for now. Lots to think about.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • Or make every 'my' inside a class definition be an instance variable ...

    --Nat

  • Yes I know I should wait for Perl 6, blah blah blah, but I have reasons for doing this so don't try and persuade me not to

    Why should you wait for Perl 6? Perl 5 is a perfectly viable platform for such experiments. I expect Perl 6 to arrive eventually and be worth moving to, but many people are still skeptical. Skeptical or not, the Perl 6 development effort ignited some spectacular development fireworks in the world of Perl 5, and we're all reaping the benefits. If you have ideas, don't let anyone

    --
    J. David works really hard, has a passion for writing good software, and knows many of the world's best Perl programmers
  • I've ranted a few times on Perlmonks [perlmonks.org] when people get "closure" and "anon sub" mixed up.

    A closure is any subroutine that needs to grab its environment because it's going out of scope, and may or may not be named.

    An anonymous subroutine is a coderef, and may or may not be a closure.

    I've got code to demonstrate all four types of subroutines (named vs anonymous, closure vs not) at Monks somewhere.

    --
    • Randal L. Schwartz
    • Stonehenge
    • Yes, but contrary to what #london may be claiming, both of Matts samples represent closures. :) Just check against Damians definition!
      • Right. The examples at the top of this thread are named subroutines that are closures. Similar to this: BEGIN { my @DoW = qw(Sun Mon Tue Wed Thu Fri Sat); sub DoW { my $n = shift; die unless $n == int($n) and $n >= 0 and $n That's definitely a closure and yet it's a named subroutine.
        --
        • Randal L. Schwartz
        • Stonehenge