Closures in Java and Scala

People argue that verbose code is easier to understand. Do you agree when reading these two?

public List<Item> bought(User user) {
	List<Item> result = new ArrayList();
	for (Item item : currentItems) {
		if (user.bought(item)) {
			result.add(item);
		}
	}
	return result;
}

def bought(user: User): List[Item] = {
	items.filter(user bought _)
}

If you are familiar with Java, which is more likely then you being familiar with Scala, you may tend to the Java-version. Scala has a different syntax for declaring types and generics, and supports closures, including anonymous parameters (the underscore).

When Closures are introduced in one of the next Java releases, JDK 7 or 8, the example could be rewritten like this:

public List<Item> bought(User user) {
	return ListUtils.filter(Item item : items) {
	   user.bought(item);
	}
}

Or with extension methods:

public List<Item> bought(User user) {
	return items.filter(Item item : ) { // <-- note the smily! thats what its all about!
	   user.bought(item);
	}
}

The interesting differences between Java with closures and Scala is the static typing: Scala inferences that items are all of type Item, so there is no need to specify that information again.

So, while the current Java Closures specification is a great step in the right direction, lead by Neil Gafter who is quite the right man for the job, it may not be worth to wait for it, if you have the choice. Its not even sure yet that we'll see that spec implemented in JDK7, and even that is at best one and a half year away.

PS: Pasting Scala code with generic types into a blog is much easier then generic Java, where you need to escape < and >

-Jörn

No more comments.
  1. jau

    In fact you can do it in Scala like

    def bought(user: User) = items.filter(_.bought)

    and it also seems very readable. One thing you have to know is the meaning of _. But it is a thing you learn only once at the beginning. When I have to come back to Java i feel .. rather annoyed by having to write all that filter, map and find methods which in Scala are natural readable oneliners.

  2. Thanks Jau, thats even shorter.

    I agree with the _ syntax: It can be daunting at first, but once learned very handy.

  3. Mark Birenbaum

    How much value do closures actually bring though? I can basically do this right now.

    
            final User  user = null; 
            List<Item> items = null; 
            
            ListUtils.filter(items, new Filter<Item>(){ 
                public boolean retain(Item  item)  {
                        return user.bought(item);
                }
              }
            );
    
    

    I’m not disputing it’s a little more verbose (I have to explicitly declare a retain method rather than just have it anonymously included as one of the ListUtils params directly), but is that really enough of a reason to generate a complex new concept in Java, like closures?

    Closures are clearly necessary in dynamically typed languages where they’re needed to provide “private” functionality, but I just don’t see how a statically typed language like Java gains from them. Or at least, not enough of a gain to justify making the language more complex.

  4. I disagree that closures are useful only in the context of dynamic-typed languages. Closures bring way more benefits then just what I covered here, one being control abstractions.

    Even in this example: Just compare your five-liner with the Scala-one-liner. Thats five times less code and still static-typed!