Skip to main content

Is function type required for closure ?

Posted by forax on September 20, 2006 at 2:41 AM PDT

As seen in Neil Gafter's blogs, there are two rival proposals
about adding closure to Java language.
The first one, named v0.1, introduces a new kind of
type, function type in order to express the type of a closure.
The second one, named v0.2, enables to use
interface as type of closure.


The goal of this entry is to show the pro and cons of the
two proposals.

Let me take an example. I want to add each integer of a list,
so i can use a closure for that.
The code bellow uses the abbreviated invocation syntax
of closure defined in section 10 of the two proposals.

 List<Integer> list=Arrays.asList(2,4,6);
int result=0;
forEach(int value:list) {
   result+=value;
}
System.out.println(result);

The code that declares and uses closure is the same for the two
proposals. A contrario, the code that defines the method forEach
is different depending of the version of the proposal.


With the proposal v0.2, closures are typed
by an interface, like that:

 public interface Performer<E> {
   void doIt(E element);
}
public static <T> void forEach(
   Iterable<? extends T> iterable,Performer<? super T> performer) {

   for(T item:iterable)
     performer.doIt(item);
}

The main interest of this way is the seamless integration with
existing codes. The code of forEach is a "traditionnal" 1.5 code
with no supplementary syntax. Futhermore,
using an interface permits to name abstraction,
it seems more clear to talk about a comparator
than a int(T,T).

Now, the same example but with the syntax describes in the v0.1.

 public static <T> void forEach(
   Iterable<? extends T> iterable,void(T) func) {

   for(T item:iterable)
     func(item);
}

Clearly, you have to learn a new syntax: void(T) is
a function that take a T and returns nothing.
Apart that fact, the syntax is not
hard on the eyes like, by example, function pointer in C.

The subtyping rules defined between function types
avoid to understand generics deeply,
void(T) seems more simpler than
Performer.

In order to use closures with an existing code the v0.1
includes the same convertion mecanism between
closure and interface that the v0.2.
So you have two ways to define forEach,
not a good point !

The bytecode used for invocation is different, the v0.1
will use invokedynamic and the v0.2 invokeinterface.
The difference is that invokedynamic don't need to box and unbox,
so the performance could be far better using a function type than
using an interface. The cost of boxing could really be a problem
because in general closure are small code and the cost of
boxing will not be negligible comparing to the cost of
executing the instructions of the closure.
Perhaps, it's not a big beal, Java has lives with that cost
since its inception and it doen't seem to be a big trouble.

And i want to end with a stupid argument, the proposal of the
v0.1 takes less line of codes that the v0.2 :)

Now express yourself, what do you think ?

Related Topics >>