Pure Danger Tech


navigation
home

JavaOne: Neal Gafter on Closures

07 May 2008

I was excited to see Neal talk about closures and I think he did a pretty good job staying focused on practical ways to use closures to reduce boilerplate. The problem with talking about closures is that it’s hard to stay focused on the practical benefits without getting bogged down into debates over syntax and features. On that front, I think Neal’s talk was a big success.

The initial part of the talk did a pretty quick ramp up on what closures are and where you might use them. One interesting comment during the talk was that he thought the Groovy -> syntax might actually be better. But ultimately, syntax is still undecided and Neal actually stated that this was only one of many proposals as the very first thing he said.

Neal quickly got into talking about aggregate operations over collections, which dovetailed very well with Brian Goetz’s talk yesterday on fork-join. These work on an array/list/map and provide operations like sort, filter, map, reduce, fold, etc. Basically a functional approach. The nice thing is that these can be automatically parallelized if you abstract it properly.

An example:

[source:java]

final double highestGpa = students

.filter({ Student s => s.graduationYear == THIS_YEAR })

.map( {Student s => s.getGpa() })

.max();

[/source]

Neal then detailed a particular use case that he used as an extended example to show how closures can reduce boilerplate. The example was something like this at the beginning: [source:java]

public void recordTime(String opName, long nanoseconds, boolean succeeded) {

long startTime = System.nanoTime();

boolean success = false;

try {

// real code

success = true;

} finally {

recordTiming(“op”, System.nanoTime() – startTime, success);

}

}

[/source]

where the “real code” is really the only “business code” and the rest is just boilerplate to do the timing. He next looked at moving that tracing code into a class, which helps a little in removing possible bugs but still has a lot of boilerplate at use time.

In talking about exception handling he made a brief detour into talking about two Java 7 exception proposals: multiple catch and rethrow. I love these ideas and it seems like the response I’ve seen on them elsewhere has been overwhelmingly positive.

With closures we can remove most of the boilerplate to get to something like: [source:java]

time(“opName”, {=>

// block of code

});

[/source]

However, this has problems due to both exceptions and returns vs no-returns. Neal did a great job of leading through all this which I won’t try to reproduce. He went through the support for exception and completion transparency and the motivation for Nothing (to indicate a method should never return anything as a closure will abort early) and Void (for method able to return early with no result). Finally, he squared the circle by demonstrating how they can both be combined with generics (my brain core dumped here).

The happy ending: [source:java]

interface Block<R, throws X> {

R execute() throws X;

}</p>

public <R, throws X> R

time(String op, Block<R, X> block) throws X {

}

[/source]

which combined with the a simplification to allow dropping the => in closures that don’t take args yields this simple API: [source:java]

time(“opName”) {

}

[/source]

Finally, Neal went through some control invocation APIs that could improve things like withStream, withLock, and eachEntry. These have been blogged about before and cover some very common cases.

For me, the exception and completion transparency sections were invaluable as those have always been fuzzy to me before now based on just looking at the spec and so forth.

I certainly hope we can get closures in Java 7. I’m now a true believer, not because of the talk but from spending some time with the prototypes and seeing opportunities for closures everywhere in my code. Neal made no predictions about whether closures would be in Java 7 or not.