Thursday, February 14, 2008

Java Closures : Introduction

Folks have been working on getting closures into the next release of Java - Dolphin or Java 7. In the past I have posted a tiny video on how to work with closures in Groovy.

Go to www.javac.info to download the closures prototype compiler and extract it. Extract the archive using tar command on linux(that is what I use for development and testing out something new on Java).

You can notice a "java" command and "javac" command. Now if you already have JDK in your path(which you should have in order to tryout the prototype compiler), you differentiate between "java" in your path and the "java" in this directory by simply doing a "./".

To compile a Closure Demo you need to say

./javac MyClosureDemo.java 

I put ./ in front of "javac" so as to differentiate between javac which is already in my path.

Now try running these commands...

$java -version
$.
/java -version

You would notice that the one with ./java returns an internal bootstrap version number while the java returns the actual 1.x release.

Lets get started and write a simple closure.Within main() method try this statement.

{String => int} myFirstClosure;
myFirstClosure
= { String name =>name.length() };

Two things to notice :
1. Firstly name is the parameter this closure takes.
2. There is no "RETURN" statement (return). Some of us not happy about the missing return and how it deviates from the-Java-way. Anyway, I do not give a damn. We should be happy about that a lot of people have put in a lot of effort to come up with something so cool. Instead of complaining, appreciate their effort.

Anyway, the last statement with no ; is returned to the closure. If there is no such statement without a ; then its a closure that returns void.

Since it returns an integer, we can declare this closure as

{ String => int } myFirstClosure; 

This is of the format

{ parameters => returnType } identifier 

As like any method, returnType is mandatory.

You invoke the closure by calling the "invoke()" method and passing to it the parameters that the closure takes in.

int Length = myFirstClosure.invoke("Something"); 

Try out the shown closure, save the file and compile using the ./javac the prototype compiler. The compilation should be successful!

Complete Code:

package screencast; // I placed the demos in this package

/**
* This is one of my first demos on how to use closure!
*/
class FirstClosure {

public static void main(String[] args) {

{ String
=> int } myFirstClosure;
myFirstClosure
= { String name => name.length() };
//{formal => returntype } identifier;

String name
= "Bhargav";

int length = myFirstClosure.invoke(name);

System.
out.printf("My name is %s and the length of my name is %d",name,length);

}
}


Ok, if you look at what was generated in the "javax" directory. You should see Interfaces in the package javax.lang.function. Some of the interfaces that I know are I, II, III and a closure is actually translated into these interfaces and its body becomes the body of the invoke() method which these interfaces define! More implementation details here.

Now run the program using

./java screencast.FirstClosure 

And you are done!!!

Get started and refer www.javac.info, there is amazing tutorial posted there!

No comments: