Pages

Monday, August 21, 2006

Closures for Java

Recently there was a proposal to add closures to Java. While this sounds like a good idea to many people who are used to have closures in their favorite language, it's in fact really useless, because Java already has closures for some time now.

In Java closures are called anonymous inner classes. Those are in fact full featured closures, because they really capture the environment of the method the closure was created in. This capturing is limited to variables declared as 'final' because to allow capturing arbitrary variables there would be the need to allocate them on the heap. This was a no-no a few years ago when Java was relatively new and slow and memory and runtime efficiency was really an issue.

Because of this, adding another syntax for closures isn't a very good idea because it only makes the language more complicated without getting something really new. Instead of this I would propose two additions to the language which could server the same purpose: Make the usage of closures more concise.

First we need a syntax to make non-final variables accessible from the closure. I propose using the keyword transient, because it's available and has no use other then on field declarations. To make a local accessible to a closure one can use this idiom:

final int[] val = new int[] { 1 };

val is now a final variable and can be accessed from within the closure. To get it's value you have of course to write val[0] everywhere. To make this more simple, I propose the following syntax:

transient int val = 1;

The compiler can then create the above code and use val[0] for each access to the variable. This little extension it's also quite easy useful for multiple return values. You can declare a method

void methodWithTwoReturnValues(transient int x,
transient int y) {
x = 10;
y = 20;
}

and use it this way:
transient int x, y;
methodWithTwoReturnValues(x, y);
// access x and y here.

So this extension serves two purposes: Make use of non-final variables with closures easier and have call-by-reference for arbitrary values.

The next addition is an easier syntax for the callsite. In the moment to use a closure somewhere you have to write something like

new ClosureType() {
int eval(int val) {
return val*2;
}
}

If the class 'ClosureType' has only a single method, this could be simplified with an easy compiler extension to:

new ClosureType()(int val) { return val*2; }

It's still not as short as possible, but it still contains all information necessary. The compiler has to look if 'ClosureType' has a single method with a single int parameter, then get the return type of this method and use this to synthesize the full method.

1 comment:

Neal Gafter said...

To see what the current proposal for closures in Java would support, but inner classes do not support, see http://gafter.blogspot.com/2006/08/use-cases-for-closures.html