Main Menu

method handles == closures ??

John Rose
(JSR 292 spec leader)
recently push a great patch that enables support
for method handles inside the VM.
A java.dyn.MethodHandle is a safe object that stands for
a function pointer but unlike a function pointer, calling a method handle
with wrong arguments raise an exception.
The aim of method handles (with invokedynamic) is to ease
the support of dynamic languages by the Java VM.
But method handles is also a good candidate to implementclosures :)

Using method handle VM support to implement closure

Let's take an example, I want to iterate over a collection
and call a method (here sayHello) on each element.
Using BGGA syntax, it's something like that:

To create a method handle, I first create its method type,
here void(Object) then I perform a lookup
using findStatic to find a static method named "sayHello"
that takes an Object and returns void.
And then I can call each with a list of String and my method
handle (linked to sayHello).

Compile and ...

And it doesn't compile :(

In each, I call invoke() on a MethodHandle
and this method doesn't exist at compile time.
Remember how a method handle works,
you always can call invoke with the arguments you want
and the VM will raise an exception if arguments doesn't match
parameter types.
So, the VM understands the call, but the compiler is not already modified
to allow to call invoke on a MethodHandle with any
arguments.

Some open questions: Are method handles more efficient than reflection ?
I think the answer is Yes but I let you that as an exercice.
BGGA spec allows co/contravariance how to do that with method handles ?
Hum, good question for a future blog entry.

No alternative to real closures i guess. Their great advantage (and great disadvantage) is that they capture the method signature perfectly, unfortunately including exceptions. That guy in the closures mailing list proposing to linearize exception handling has a nice idea since that would mean no throws exception E garbage in closures accepting methods, but that requires that closures do not escape the method boundaries, so no closure variables, which IMO only makes sense.
I think that closures are a FP concept, and so, should not be able to be saved in variables. If that does not mean that we can't refer to a method as a closure. MyObject#method() or whatever makes perfect sense.

I'm no language expert, but closures' definition didn't have that 'lexical scope variable binding' thing? This is what makes closures substantially more powerful than function pointers.
For example, without it, you couldn't do something like (Groovy syntax)
StringBuffer buffer = ...;
list.each { s -> buffer.append(s) } // references a local variable 'buffer' from the block that contains the closure
, which is a pretty common idiom in languages that support closures.

Or we could let Java be Java and when we want to use a dynamic language we use a dynamic language. I've been writing and reading Java for over 10 years now, and I have to admit that reading the code above gives me a slight headache and bit of nausea.
Here's how we do it in Groovy:
messages.each { println "hello ${it}" }
Of course Groovy already has closures. And Java-like syntax. And runs on the VM.
Chasing C# is just pushing more and more Java developers to Ruby and Groovy.

A MethodHandle is definitely not as simple as a C function pointer. It is a far more complex
construct than that! What Remi is saying is that the MethodHandle can (and should) be used
to implement closures, or to be more precise, hold on to closures. The MethodHandle by itself does
not give you lexical scoping and all the other goodness that you need.