What flavor of closures?
I just attended Josh Bloch's presentation at JavaPolis, where he asks the community whether they want Java to support function types, or if they'd prefer that people write these things the way they do today. His examples are carefully selected from the most twisted of the test suite. Compiler test suites are a good place to find the most twisted but unrealistic uses of any given language feature. I thought it would be interesting to look at the question in the context of a real API. You probably know my opinion, but just to be clear, here is an excerpt from Doug Lea's fork-join framework
/** * An object with a function accepting pairs of objects, one of * type T and one of type U, returning those of type V */ interface Combiner<T,U,V> { V combine(T t, U u); } class ParallelArray<T> { /** * Returns a ParallelArray containing results of applying * combine(thisElement, otherElement) for each element. */ <U,V> ParallelArray<V> combine( ParallelArray<U> other, Combiner<? super T, ? super U, ? extends V> combiner) { ... } }
And the equivalent code ported to use the features of the closures spec:
class ParallelArray<T> { /** * Returns a ParallelArray containing results of applying * combine(thisElement, otherElement) for each element. */ <U,V> ParallelArray<V> combine( ParallelArray<U> other, { T, U => V } combiner) { ... } }
The question Josh asks is this: which version of this API would you prefer see?
The point he makes is that function types enable (he says "encourage") an "exotic" style of programming - functional programming - which should be discouraged, otherwise the entire platform will become infected with unreadable code. Although functional programming is just as possible with or without function types - they are just shorthand for interface types, after all - Josh prefers the language provide syntactic vinegar for these techniques.
Part of his talk was about the problems of being able to use nonlocal return by default in a closure. See my previous blog post for a description of how this theoretical problem won't exist in the next version of the spec, and doesn't exist in the prototype today.
Finally, Josh showed that if you want to use something like eachEntry to loop over a map, and you want to be able to use primitive types for the loop variables, autoboxing doesn't work and you'd have to define 81 different versions of the eachEntry method (one for each possible primitive type in each position). That's true, just as it's true that you'd have to define 81 different versions of the Map API if you want to be able to handle primitives in them. If it turns out to be a good idea to make autoboxing work for the incoming arguments to a closure, that is a small tweak to the closure conversion. These kinds of issues can be addressed in a JSR.
Josh's vision for an alternative is Concise Instance Creation Expressions along with adding a moderate number of new statement forms.