Click here to read this article in Portuguese.
I quited, long time ago, trying to keep pace with latest tech trends on programming languages. I remember when I started programming, using Clipper, all the news you could get was either by buying a book or a magazine.
Today, when you visit a Digg-like website for programming news, you’ll probably end up finding 3 new and completely revolutionary AJAX toolkits, two articles saying why language x sucks and other three saying it is the best thing since sliced bread, new languages, benchmarks, etc… This scenario obligates you to filter new technology and just investigate whatever you think will be important for your skill set. It’s either that or getting really mad and/or shallow.
Well, some time ago I began to read about Java Closures but never figured out what it was and I really didn’t want to bother about it. Yes, but that was before I found Google Tech Talks, and of more interest, the Advanced Topics on Programming Languages series. I watched a 2-hour talk about Java Closures and finally understood it. Actually it was more than that, I started to like Java Closures.
The principle behind Closures isn’t new. It’s about having code blocks in form of variables. I remember that we had that in Clipper back in 1996. But the new Java Proposal goes beyond, allowing some syntax changes that, in my understanding, makes all the difference. I’ll try to give a brief explanation on what I understood on the topic.
If you ever messed with JDBC or Sockets code, you know there are a lot of boring code to write, something like:
public List getCustomers() {
List result = new ArrayList();
Connection conn;
Statement s;
ResultSet rs;
try {
conn = ConnectionPool.getConnection();
s = c.createStatement();
rs = s.executeQuery("SELECT * FROM CUSTOMER");
while (rs.next()) {
// ...
}
} catch (SQLException e) {
System.out.println("Error...");
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
}
}
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
}
}
if (c != null) {
try {
c.close();
} catch (SQLException e) {
}
}
}
}
On this code you notice you have 37 lines but business logic is concentrated on lines 7 to 13, or 16% of the code here is business logic. So, when a friend of mine says he doesn’t like Java because it is a bureaucratic language, I have to give in. Imagine having hundrets of data access methods like this on your code. Isn’t it really a lot of duplicated code? Shouldn’t it have a better way of doing this?
Well… Closures to the rescue! 🙂 What if we could write something like:
public List getCustomers() {
Connection conn;
Statement s;
ResultSet rs;
with(conn, s, rs, { =>
conn = ConnectionPool.getConnection();
s = c.createStatement();
rs = s.executeQuery("SELECT * FROM CUSTOMER");
if (rs.next()) {
// ...
}
});
}
That’s the new java construct that is being planned to be implemented on JDK7 codename Dolphin. But even better than what we have above, there is an additional construct, called control abstraction syntax. Take a look:
public List getCustomers() {
Connection conn;
Statement s;
ResultSet rs;
with (conn, s, rs) {
conn = ConnectionPool.getConnection();
s = c.createStatement();
rs = s.executeQuery("SELECT * FROM CUSTOMER");
if (rs.next()) {
// ...
}
}
}
This snippet of code is translated to the exact same thing as before. This new construct states that a method invocation with a trailing code block is automagically translated into a closure in compile time. Look how elegant and straightforward this method now is. When you read it, you don’t get distracted by a lot of statements that has nothing to do with business logic.
What about the with
method? How would it look like?
public void with(Connection c, Statement s, ResultSet rs, { => void } block) {
try {
block.invoke();
} catch (SQLException e) {
System.out.println("Error...");
e.printStackTrace();
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
}
}
if (s != null) {
try {
s.close();
} catch (SQLException e) {
}
}
if (c != null) {
try {
c.close();
} catch (SQLException e) {
}
}
}
}
The last parameter on that method is the new closure construct. Closures can take parameters and have a return value as well as optionally throw exceptions. Here are some sample closure types:
{int => int}
{int, int => int}
{String => int throws NumberFormatException}
{ => void }
{T => U}
And implementations:
{int x => x+1}
{int x, int y => x+y}
{String x => Integer.parseInt(x)}
{=> System.out.println("Hello world");}
{int, int => int} sum = {int x, int y => x+y}; // sums up x and y
This article is intended to get you started on java closures. For more in-depth understanding watch the first class presentation by Neal Gafter, one of the authors of the closures specification. Here is the link.
Related links:
Neal Gafter site about closures
Neal Gafter blog
Peter Ahé’s Weblog (other author of the specification)
James Gosling, about closures
Article: Achieving Closures
Wikipedia Article on Closures
Joshua Bloch on Closures, Resource Management, Google has some good arguments on Closures