dagblog.
← Archive

Closures in Java and the revolt of the functions


Few things about Java have caused as much of a stir lately as the proposal to add function types and inline functions called closures, by Gilad Bracha, Neal Gafter, James Gosling and Peter von der Ahé. Languages such as Ruby, Scala, Smalltalk and JavaScript directly support function types. What would this mean for Java? What would the syntax look like, and how have closures been received? Those are the questions we’ll try to answer.

Java supports anonymous inner classes. We all know and use them. Here’s a quick example as a reminder.

List persons = ...;

Collections.sort(persons, new Comparator() {

 public int compare(Person a, Person b) {

 return a.getAge() - b.getAge();

 }

});

The sort method takes two arguments, the list to sort and a comparator that implements the comparison. Here the comparator is an anonymous inner class.

Closures

The document introduces the idea of an anonymous function, also called a closure. In our example, we could replace the comparator’s anonymous inner class with an anonymous function. The code could then look like this.

List persons = ...;

Collections.sort(persons, int(Person a, Person b) { return a.getAge() - b.getAge()});

The code int(Person a, Person b) {return a.getAge() - b.getAge();} is the anonymous function, or closure. At compile time the closure translates to exactly the same code as an anonymous inner class. The proposed syntax allows the return type to be inferred.

Collections.sort(persons, int(Person a, Person b) : a.getAge() - b.getAge());



Collections.sort(persons, int(Person a, Person b) { a.getAge() - b.getAge()});

Closure syntax should allow a shorter form, with the closure fitted in as the method’s second argument.

List persons = ...;

Collections.sort(persons) int(Person a, Person b) {

 return a.getAge() - b.getAge();

}

Local functions

A local function’s signature specifies its arguments, return type and any exceptions in the throws clause.

int plus2(int x) { return x+2; }

A local function also has a reference type. Here it is assigned to a variable of that type.

int(int) plus2b = plus2;

You can then call it as a local function.

System.out.println(plus2b(2));

Putting it all together

public static void main(String[] args) {

 int plus2(int x) { return x+2; }

 int(int) plus2b = plus2;

 System.out.println(plus2b(2));

}

Impact on the language

Local functions, of which closures are the anonymous form, add a new dimension to Java. If the object has been the fundamental construct so far, local functions mean we have to count the function as well. Unlike an object, a function has no internal state and its interface is defined by input and output.

So we can write a method with a function as one of its arguments and have the method work with it.

/**

 * Obecná metoda pro hledání v seznamu osob, vlastní hledání je 

 * definováno na úrovni funkčního typu.

 * 

 * @param concreteFinder funkce která implementuje hledání

 * @return seznam osob

 */ 

public List find(boolean(Person) concreteFinder) {

 List persons = ...//načtení dat např. z DB

 List foundPersons = new ArrayList();

 for(Person p: persons){

 if(concreteFinder(p)){

 foundPersons.add(p);

 } 

 }

 return foundPersons; 

} 



//lokální funkce, která vrací true v případě, že je osoba nezletilá

boolean(Person) teenFinder = (Person p) : p.getAge() < 19;



//použití

List teenagers = find(teenFinder);

Reactions

So far there seem to be far fewer developers licking their lips than feeling confused. Setting aside the ultra-geeks, I get the impression that very few developers have been longing for this. The usual reaction could be summed up as “Do I really need this?” These syntactic acrobatics, and I don’t know what else to call them, have the undeniable drawback of breaking backward compatibility and making code harder to read. Of course, we should judge them by the more advanced constructs, such as function subtyping boolean(Person) teenFinder = (Female f) : f.getAge() < 19;
or casting, and keep in mind that the comparator is only an illustration.

The future

The exact specification of closures and local functions is still being worked out, so some of the above may not hold in the future. If closures make it into Java, it should be in version 7. The related links are conveniently gathered in the article Closures Syntax in Java 7.

Medium version

Related articles

Related CZ Podcast episodes