(I wrote the original version of this page in 2002. I've made a few minor edits and added a comparison with Java's anonymous inner classes)

I briefly worked with a team that used Perl to implement high availability web applications. When discussing the language with the team’s technical lead, I pointed out that I was impressed with the fact that Perl implemented closures. Having written a Scheme interpreter, I considered closures a fundamental component of modelling procedures.

This led to a discussion of what was a closure, and what was it good for?

A closure encapsulates the execution of a one or more operations for side effects and/or the return of a value in the environment of the function’s definition where the closure was created.

From this definition, all functions, procedures, and methods in languages such as Java and Visual Basic are closures. When a programmer refers to a language as implementing closures, (s)he is really saying that the language permits the creation of arbitrary closures at run time. Scheme aficionados would say that languages like Perl, Lisp, and Ruby support first class closures: closures can be arbitrarily created and assigned as values to variables or returned from functions.

Since contemporary programming languages are lexically scoped, the environment of the function refers to the variables in scope at the time the function is defined. This includes temporary variables, variables that are normally created on some sort of stack and discarded when they “go out of scope.” When a closure is created, variables in scope must be preserved until the closure itself ceases to exist.

Here’s a Ruby closure demonstrating the fact that it ‘captures’ a variable in the scope of its definition:

def makeCountervar = 0lambda dovar +=1endend

c1 = makeCounterc1.callc1.callc1.call

c2 = makeCounter

puts "c1 = #{c1.call}, c2 = #{c2.call}"

The two important things from this example are:

Although var is no longer in scope once makeCounter returns, Ruby saves it for use in the closure.

Each invocation of makeCounter creates a different var. The two counters do not interfere with each other.

What can you do with closures? Here’s something a bit more useful, a call-by-need thunk factory:

In this example, you have a simple facility for memoizing closures: they can be called repeatedly, but they only evaluate their operations once (provided the retun value is not nil). Obviously, this should not be combined with the previous example: call-by-need thunks are useful when there are no side effects of their evaluation.

Why Java's Anonymous Inner Classes do not implement closures

At first glance, an anonymous inner class in Java looks like it captures an environment. It has access to its enclosing instance's members. That looks an awful lot like the way a closure captures its environment.

But an anonymous inner class cannot access method variables or parameters. This is a crippling limitation. Consider:

I agree that in this example it will appear to produce the same result. If you like, please email and I will post another example where "final" will not work.

What is actually happening is this: Java will let you make something that looks like a closure, provided that it can optimize the result so that it is not a closure.

Allowing final variables from the enclosing scope is free because Java actually optimizes this into a copy operation.

p.s. It seems unfair for me to say "I'll change my example if you can find a way to make it work in Java," but remember that we can always find a way to make any Turing complete language produce the same result. What's under discussion is the way in which we express the mechanism for producing the result. making the paramter final actually says something quite different.

Very quickly, the reason why allowing final variables is not the same thing as creating a closure is this:

Allowing a variable in scope means allowing both read and write access to the variable. Thus, the inner function or block must be able to update the variable.

In Java, you must use idioms like the one element array or an object with a getter/setter to force the variable onto the heap. In effect, ou're creating a Scheme-to-Java compiler where you are doing the translation by hand.

You aren't using a closure. This is painfully evident when you want to use closures regularly. You must constantly think about each variable: "will I need this in an enclosed scope? If so, declare it like this and access it like this. If not, declare it like that and access it like that."