Understanding the closures debate

Does Java need closures? Three proposals compared

With three proposals vying for inclusion in Java 7, understanding closures and the arguments for and against their inclusion in the Java language is essential. In this article Angelika Langer and Klaus Kreft give us a detailed overview of the three proposals -- BGGA, CICE, and FCM -- discussing the pros and cons of each, where they differ, and how they compare. The authors also explain the arguments against adding closures to Java 7, and conclude with their insight into where this debate will lead in the year ahead.

Closures, also known as blocks, are far from new to computer science. They're a standard feature in older languages such as Scheme, Smalltalk, and Lisp, and have more recently made their way into dynamic languages such as Ruby and Groovy. Closures are a natural fit for statically typed, functional Scala, and recently many have argued that they have a place in the Java language, too.

Many developers argue, conversely, that closures are a bad fit for the Java language. According to this camp, adding closures would be the proverbial "nail in coffin" for the already stuffed syntax of a language that tries to do too much. The end result: a hot debate, which has been making its way toward the JCP, and around the conference circuit and the blogosphere, for more than two years.

While the closures debate may seem best left to Java linguists, the inclusion of closures in Java 7 -- or not -- will ultimately affect anyone who writes Java code. In this article we provide an overview of the new functionality being proposed for the Java language. We start with a simple introduction to closures, then explain how each proposal would integrate them onto the Java language syntax. We also discuss each proposal's cost in terms of complexity. We consider the issue of closure conversion -- essential for backward compatibility with older programs -- and then delve into one of the most controversial aspects of the BGGA proposal: control abstractions.

Throughout the article we compare the pros and cons of the functionality each proposal would bring to the Java language, using code snips to demonstrate their impact on the Java programming experience. We conclude with an overview of the arguments for and against closures, as well as some insight into where these discussions may lead us in the year ahead.

So, what are closures?

Essentially, a closure is a block of code that can be passed as an argument to a function call, which will execute the block immediately or some time later. To some extent, a closure is similar to an unnamed (or anonymous) function. There is more to it, but for the time being, let us stick to this definition.

To better understand the purpose of closures, consider a simple example of a situation where you would want to pass a block of code to another function for repeated execution: a method forEach that takes a sequence of objects is supposed to apply a given functionality to every object in the sequence. How would you pass the functionality to the forEach method? Today in Java, you would have to define an interface, say Block, and pass implementations of that interface to the forEach method, as shown in Listing 1.

Listing 1. Java programming without closures

public interface Block<T> {
      void invoke(T arg);
    }
    public class Utils {
      public static <T> void forEach(Iterable<T> seq, Block<T> fct) {
        for (T elm : seq)
        fct.invoke(elm);
      }
    }
    public class Test {
      public static void main(String[] args) {
        List<Integer> nums = Arrays.asList(1,2,3);
        Block<Integer> print = new Block<Integer>() {
          public void invoke(Integer arg) {
            System.out.println(arg);
          }
        };
        Utils.forEach(nums,print);
      }
    }

The example is admittedly contrived and extremely simple, but consider it: how often in Java do you find yourself implementing an interface and passing the implementation to a method for execution? We can think of three immediate examples:

  • Runnable and Callable, which we pass to threads or thread pools for asynchronous execution.
  • Callback interfaces such as ActionListener, which we register for future execution in case a certain event occurs.
  • Comparator, which we pass to a TreeMap for maintaining its sorting order.

In all these cases we use an interface, providing some functionality as an implementation of the interface. We then pass the functionality to a method for immediate or delayed, synchronous or asynchronous execution. Closures would simplify this process by allowing a more concise syntax, thereby eliminating some of Java's verbosity. Beyond allowing more concise and readable Java source code, closures would add some functionality completely new to Java, such as custom control structures, which we explain later in the article.

Closures vs inner classes

In a recent blog post, James Gosling (aka Mr. Java himself) discussed the history of closures in Java:

Closures were left out of Java initially more because of time pressures than anything else. In the early days of Java the lack of closures was pretty painful, and so inner classes were born: an uncomfortable compromise that attempted to avoid a number of hard issues. But as is normal in so many design issues, the simplifications didn't really solve any problems, they just moved them.

Gosling precisely describes our present situation: for eleven years, since the release of JDK 1.1, we've been using inner classes in place of closures. While they have served us well (you might recall how difficult and frustrating it was to implement callback interfaces without them) inner classes have never truly replaced closures. They simply are less powerful and more verbose than they need to be.

So, one thing all of the closures proposals agree to is the need to conceptually replace inner classes with a more powerful programming construct. Adding closures to the Java syntax would not mean losing inner classes; rather, the two constructs would be compatible and interchangeable. The advantage of closures, of course, is that they add flexibility and power not found in inner classes.

In the next section we'll look at the specifics of how each proposal would bring closures to Java 7.

1 2 3 4 5 Page
Join the discussion
Be the first to comment on this article. Our Commenting Policies
See more