[Chicago-talk] The "other" closure

Steven Lembark lembark at wrkhors.com
Wed Dec 3 12:07:03 CST 2003



-- Jim Thomason <jthomasoniii at yahoo.com>

> {
>   my $static = 0;
>   sub foo {
>     print STDERR "I've been called ", ++$static, "
> times\n";
>     #...do interesting things
>   }
> }
>
> Voila! A closure.

This is a really nice example of a private static
variable, but it is not a closure. The difference
is that all invocations of the foo sub here will
share the same value of $static.

Another example:

	sub return_incrementor
	{
		my $value = shift; # lexical value

		sub { ++$value }
	}


	my $from_zero = return_incrementor 0;
	my $from_nine = return_incrementor 9;

	for( 1.. 10 )
	{
		print "From zero: " . $from_zero->();
		print "From nine: " . $from_nine->();
	}

The important thing to notice is that the "return_incrementor"
subroutine will create a new, unique lexical value of $value
each time it is called. This means that the $from_zero and
$from_nine incrementor sub's will get their own private values.
Nothing about the $value returned with the first call of
return_incrementor has antyhing to do with the value used in
the second call.

That's what makes them a closure: the storage used in the
anonmous subroutine is private to the specific instance;
creating multilpe anonymous subroutines gives each of them
their own storage.

You can create multiple closures that share the same data
(e.g., one to increment another to decrement the same value).
They are still closures because each SET of subroutines
gets its own private copy of the data -- creating ten sets
of closures will give you ten separate, distinct, unrelated
pieces of storage shared among the set of closures.



Closures work (grab a drink for this one) becuase Perl uses
reference counting for its variable maintinence. If you look
at the return_incrementor sub:

	{						<--	lifespan of the name "$value"
								is defined by the enclosing
								braces.

		my $value = shift;	<-- new $value has a ref count of one.

		sub { ++$value }  	<-- used $value has a ref count of two.

	}                     	<-- scope reduces $value to ref count of one.


The trick to closures is that $value is kept alive by the
anonymous subroutine's use of it. The name "value" goes
out of scope but the storage associated with it is still
available to the anonymous subroutine. The name "$value"
is associated with a NEW piece of storage each time the
return_incrementor subroutine is called. The new storage
begins life with a reference count of one but can be
kept alive when the name goes out of scope by being used
in another structure (subroutine in this case).

Note that if the variables $from_zero or $from_nine ever
go out of scope the anonymous subroutines will be destroyed
and the reference count of the separate storage for their
respective $value will go to zero. At that point the $value
storage will be reclaimed.

		

--
Steven Lembark                               2930 W. Palmer
Workhorse Computing                       Chicago, IL 60647
                                            +1 888 359 3508



More information about the Chicago-talk mailing list