Here's how to get everything you need from closures today in Java, without waiting for the big foreheads to argue over how to make it nice and perfect.

You've almost certainly used something sort of closure-like when you've used the Runnable interface. You can for example create an anonymous subclass of Runnable and .run() it:

  Runnable closure = new Runnable() {
 void run() { System.out.println("Hello"); }};
closure.run(); // prints Hello

In particular in Java Thread class implements Runnable. You can do more interesting things, for example:

  StringBuffer _myString = new StringBuffer("Hello");
// Java will only close around final variables because it's dumb
final StringBuffer foo = _myString;
Runnable closure = new Runnable() {
public void run() { System.out.println(foo); }
};
closure.run(); // prints Hello

This is why it's called a closure -- the anonymous subclass Closes Around the variables in the scope in which it's defined. So, it has access here to myString. If you change _myString in the original context the closure will use the new value.

You can pass closures around, for example pass it to another method in another class, and it will still remain closed around the Original context. Like this:

  public void anotherContext( Runnable closure ) {
StringBuffer foo = new StringBuffer("Goodbye");
closure.run(); // still prints Hello from its own context
}

This is all available out of the box in Java, a little boring. It would be interesting if the closure could work on variables BOTH from its original context and that you pass into it at the same time. This can be done, but Runnable doesn't allow it, so we'll make our own Runnable:

// A general-purpose closure class that can receive and
// return values when you call it.
// This is an abstract class... override these functions for
// whatever kind of closure you need.
// If you call a non-overriden function, it will throw you.
public class SemaRunnable {
public void run() { throw new RuntimeException("Must override SemaRunnable.run()"); }
public Object run( Object param ) { throw new RuntimeException("Must override SemaRunnable.run()"); }
}

Now I can do a simple example (from the Wikipedia article):

SemaRunnable bestSellingBooks = new SemaRunnable() {
public Object run( Object thresholdObject ) {
int threshold = ((Integer)thresholdObject).intvalue();
// assume bookList is in the local context:
myBookList = bookList.booksWithSalesGreaterThan(threshold);
return myBookList;
}
};
// call books = bestSellingBooks.run( Integer(5000) );

Here's a more complete example. In some code I'm working on, I need to pass an image -- not just an image, but also the ability to get just a subImage of that image. I don't want them to have to know how to do image manipulation. Here is how I do it using closures:

    SemaRunnable getSubImage = new SemaRunnable() {
      public Object run( Object param ) {
        int x = Array.getInt(param,0); // these four variables
 int y = Array.getInt(param,1); // are coming in
        int width = Array.getInt(param,2); // from the
 int height = Array.getInt(param,3); // caller
// Now I will close on a method in my local context:
        short[] subImg = dataForSubImage( x, y, width, height );
return subImg;
      }
    };
someObject.setClosureToBe(getSubImage);

...

// This method is being closed upon in the local context:
public short[] dataForSubImage( int x, int y, int width, int height ) {
...

someObject in some completely different part of my code, gets the closure and calls it like this:

  // completely different class, which received closure object
int [] subImageData = (int[])closure.run( new int [] {new_x, new_y, new_w, new_h} );

You don't have to call it closure. And you can pass as many params either way as you like, storing them in arrays, since array is an Object in java.

But... but... but..., people will say, why not create a class which does this, and import the class, and construct the class, and make calls on the class, it would do the same thing. They just answered their own question: it requires lots of LOCs.

And there's other good reasons. For example, let's say you have two versions of your function for different situations, you can simply swap them out of they are closures. The beauty of it is, the java compiler doesn't know or care what's happening, because everything is just SemaRunnable and Object. So it's not going to complain that a function or class name has changed. That means metaprogramming goodness. Sweet.

So, practical closures in Java. It may look a little unfamiliar at first, but once you know how to do it it's easy and can be really useful.

EXTRA SPECIAL BONUS: An implementation of the full monty, closure that takes a closure, makes a new closure from it, and returns that. I promised myself I'd go to bed early, but instead I stayed up and wrote you this code which is guaranteed to actually work, because I tried it. Try running it.


// By: Simon Woodside sbwoodside (a)(t) gmail (d)o(t) com
// See: http://simonwoodside.com/weblog/2009/7/7/a_little_bit_more_serious/

// To try this out:
// % javac Test.java && java Test

// Demonstration of how to do closures in Java
// In this case, |derivative| is a closure which approximates derivatives, and
// |sineDerivativeApproximator| approximates the derivative of ... you guessed it ... sine.

// It's hard to believe, given how much code there is, but in javascript this would be:
// function derivative(f, dx) {
// return function(x) {
// return (f(x + dx) - f(x)) / dx;
// };
// }
// (See http://en.wikipedia.org/wiki/Closure_(computer_science) )

import java.util.*;
import java.lang.reflect.*;
import java.lang.*;

public class Test {
public static void main (String args[]) {
System.out.println("Closures coming up!");
Test test = new Test();
test.go();
}

// SemaRunnable is a general-purpose closure class that can receive and
// return values when you call it.
// This is an abstract class... override these functions for
// whatever kind of closure you need.
// If you call a non-overriden function, it will throw you.
public class SemaRunnable {
public void run() { throw new RuntimeException("Must override SemaRunnable.run()"); }
public Object run( Object param ) { throw new RuntimeException("Must override SemaRunnable.run()"); }
}

void go() {
// Let's start with a really simple example.
// See my blog post for more details:
StringBuffer _myString = new StringBuffer("Hello");
final StringBuffer foo = _myString;
Runnable closure = new Runnable() {
public void run() { System.out.println(foo); }
};
closure.run(); // prints Hello

// Now let's do something more fun.
// A closure that receives a closure and returns a new closure.
// This is going to be wordy because Java Arrays and Number objects are TERRIBLE

// Return a function that approximates the derivative of f
// using an interval of dx, which should be appropriately small.
SemaRunnable derivative = new SemaRunnable() {
public Object run( Object params ) {
// params must be { SemaRunnable f, Float dx }
final SemaRunnable f = (SemaRunnable)Array.get(params,0); // get f
final float dx = ((Float)((Object[])params)[1]).floatValue(); // get dx
SemaRunnable approximator = new SemaRunnable() {
public Object run( Object xFloat ) {
float x = ((Float)xFloat).floatValue();
float fOfXPlusDx = ((Float)f.run( new Float(x + dx) )).floatValue();
float fOfX = ((Float)f.run( new Float(x) )).floatValue();
float answer = (fOfXPlusDx - fOfX) / dx;
return new Float(answer);
}
};
return approximator;
}
};
// Now create a closure that will simply return the sine(x):
SemaRunnable sineClosure = new SemaRunnable() {
public Object run( Object xFloat ) {
double sine = Math.sin( ((Float)xFloat).floatValue() );
return new Float(sine);
}
};
// And finally put it all together:
SemaRunnable sineDerivativeApproximator =
(SemaRunnable)derivative.run( new Object [] { sineClosure, new Float(0.001) } );
for( double x = 0.0; x<3.1416; x+=0.1 ) {
Float result = (Float)sineDerivativeApproximator.run(new Float(x));
System.out.println( "Sine(" + x + ") = " + result );
}
}
}

I ran out of time to demonstrate this, but you can also modify variables in the context from inside the closure, even though they are final, by creating a final array containing the variable, and then modifying the object contained in the array. It's not pretty but it works.