Closures: Cheers, Library Issues and Solutions

At last. But there is a problem...

I think the addition of Closures are the biggest change yet made to Java. Closures change the way you think about programs - a step change rather than a simple evolution like Generics were.

It's good to be able to do this:

int total = 0;
void(int) totalizer = (int i) : total = total + i;
totalizer(1);
totalizer(2);
System.out.println(total); // Prints 3

But what you really want is to be able to do things like this:

int[] numbers = new int[] { 100, 200 };
numbers.each(totalizer);
System.out.println(total); // Now prints 303;

This is a fairly serious problem. Without support from many of the system classes - especially Collections, closures are really quite limited. So this is why it's a real shame that it has taken so long to get Closures into Java.

I think the most useful additional collection methods would be:

  • each - run the closure once for each collection element
  • transform - return a collection of elements that are returned by using the closure once for each input collection element
  • all - return true if the closure returns true for all collection elements
  • any - return true if the closure returns true for any collection elements

On the face of it there are 3 options:

  1. break backward compatibility
  2. break closures by lack of collection support
  3. add static methods like Collections.each(Collection c, Closure x);

Option 1 may seem like a good idea to many, but it won't happen. Sun are very strong on keeping backwards compatibility.

Option 2 is just giving in without trying.

Option 3 maybe the best, but it's not really a great answer.

However I wonder if there isn't a fourth option: Some extra syntax sugar like this could replace the need for things like Collection.each(Closure c):

for (numbers : totalizer);

Behind the scenes the compiler does this:

for (Object obj : numbers.iterator) {
  totalizer(obj);
}

Clearly this should work with anything that is Iterable and not just lists.

However, this doesn't fix the lack of all() and any() methods or transform() (unless we allow a return value from the new for loop). Might it be possible to create a syntax like this to cope with all eventualities? Maybe the new for syntax could optionally take 2 closures, the first was an action to take on each collection element and the second was a combiner that allowed you to specify how the loop functioned???

Comments

Comments have been turned off on old posts