Monday, March 17, 2008

Closures: Control Abstraction, Method References, Puzzler Solution

The Java Closures prototype now supports control abstraction andimplements restricted closures and function types. The syntax haschanged slightly. Also, as hinted in thedraft JSRproposal, there is now support for eta abstraction, whichis called method reference inStephenColebourne's FCM proposal. We haven't updated thespecification, so this will serveas a brief tutorial on the changes until we do. I don't know if thiswill be the syntax we will end up with, but it will do for now. Finally,we look at solutions to the closure puzzler in my previous post.

Control Abstraction

The first thing you'll notice when using the new prototype is thatthe compiler gives a warning when a closure uses a local variable from an enclosing scope:

make sure the variable is not the target of any assignment expression; or

put @SuppressWarnings("shared") on an enclosing method or class; or

use an unrestricted closure, by using the ==> token instead of the => token (when possible).

The => token builds a restricted closure thattriggers this warning. Restricted closures also do not allow abreak or continue statement to a target outsidethe closure, nor a return statement from the enclosing method.You will rarely want to write an unrestricted closure; many (but not all) ofthe things you need to do with an unrestricted closure can be expressed moreclearly with a control invocation statement instead.

You're not allowed to assign an unrestricted closure to a restrictedinterface. A number of existing JDK interfaces, such asjava.lang.Runnable, have been modified to be restricted.

In the less common case that you're writing a method intended to be used as a controlAPI, you can write a function type with the (new) ==> token to designatean unrestricted function (interface) type. Let's do that to write a method,with, that will automatically close a stream for us. The idea is to be ableto replace this code

Method References

A natural companion to closures is a way to refer to an existing method insteadof writing a closure that accepts the same arguments and just invokes the method. This issometimes known as etaabstraction or methodreferences. We expect closures in their final form to include support for thisconvenient feature, which is why it is called out in thedraft JSR proposal. Thelatest version of the prototype supports this, with a syntax based on javadoc conventions.Here are a few examples: