Russel Winder's Website

Java, Maps and Closures ( and Erasure )

On his blog, Neal Gafter has written about the for keyword that he is proposing for addition to Java to support closures. I am a great fan of closures and closure-based programming, so I like Groovy and Ruby. The declarative expression that is achievable with languages like these makes for short programs with fewer errors. In this sense, adding closures to Java seems quite exciting. However, I wonder if this is going to end badly, like the generics situation - I believe erasure has been, and continues to be, a bit of a disaster (I have written previously on this).

This makes me wonder if closures should actually be left out of Java and that more use should be made of Groovy and dynamic languages like it for creating JVM-based systems - after all Groovy is symbiotic with Java, not a competitor.

Neal starts with a Java method:

private Droid seekDroid ( final Map map ) { for ( Map.Entry entry : map.entrySet ( ) ) { final String droidName = entry.getKey ( ) ; final Droid droid = entry.getValue ( ) ; if ( droid.isSought ( ) ) { System.out.printf ( "'%s' is the droid we seek.%n", droidName ) ; return droid ; } } return null ; }

and proposes that a better way of expressing this is:

Droid seekDroid(Map map) { for eachEntry(String droidName, Droid droid : map) { if (droid.isSought()) { System.out.printf("'%s' is the droid we seek.%n", droidName); return droid; } } }

OK, a little bit less boilerplate (at the expense of a new keyword) but that is all it is. The example does not get to the heart of what closures should be used for. The above is still an explicit iteration construct, and the whole point of closures is to invert flow control completely. In Groovy the above can be written:

def seekDroid ( map ) { def droid = map.find { droid -> droid.value.isSought ( ) } if ( droid != null ) { printf ( "'%s' is the droid we seek.%n", ) ; } droid }

The point here is that the iteration is inside the find method that Groovy adds to the Map class (via its meta-object protocol). Neal says they do not want to add methods like this in Java because of incompatibilities with existing interfaces. He then proceeds to propose adding a method to java.util.Collections, which appears to be becoming the dumping ground for all the things people want but can't have due to backwards compatibility.

It seems then that backwards compatibility is going to drive all discussion of closures and Java, just as it did generics and Java. Generics only made it in to Java by ignoring all the parameterized type information at run time, i.e. we got type erasure. This is a horrible thing avoided by all other languages with parameterized types, C# for example.

It seems the fudges to get closures into Java are starting. Of course, it would be nice if Neal and co. find a way of doing it nicely and cleanly, I fear they will not, and Java will get messier. Personally I use Groovy, it already has what Neal wants to put into Java, cleanly and neatly. Case closured.

Copyright © 2017 Russel Winder -