<< Upgrades | Home | Improving the quality of conference talks >>

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???

Tags :


Linked code blocks

What is needed is a way to effectively 'add' methods to existing classes. And a syntax isn't hard. I'll give an example without closures, and let you expand the concept:

public class Collections {
 @linkedMethod(name=Sort)
 pubilc static void sort(List list, Comparator comp) {
   ...
 }

public MyClass {
 pubilc void myMethod() {
  List list = ...;
  Comparator comp = ...;
  list.Sort(comp);
 }
}

Its a very simple syntax sugar. Any OO style method could be defined as a static method taking the object as the first parameter (sort in this case). The @linkedMethod attribute indicates that the method can be called in an OO way using the first argument as the target.

I've deliberately setup a coding standard that linked methods would be capitalised, so someone reading the code could easily tell the difference.

I'd suggest something like this is an essential addition alongside closures. :-)

Re: Closures: Cheers, Library Issues and Solutions

C# 2.0 has a very clever implementation of this called "Extension methods", see this section in Wikipedia: http://en.wikipedia.org/wiki/C_Sharp#C.23_3.0_new_language_features

In Ruby you can reopen classes and add new methods which is a relatively unsafe way of doing it. C# 2.0's implementation is a lot safer.

Re: Closures: Cheers, Library Issues and Solutions

In addition to C# extension methods, another alternative is what Scala provides as "implicit" - they <font face="Tahoma" size="2">are a very useful technique to make new libraries interact with old ones. Have  alook at Martin Odersky's comments in http://www.artima.com/forums/flat.jsp?forum=106&thread=173229&start=15&msRange=15.  </font>

Add a comment Send a TrackBack