Thursday, June 26, 2008

Jazoon: The Closures Controversy

If you ever wanted to know if it is possible to go through 60 information-packed slides in 50 minutes: Yes, it is. I've been there and Joshua pulled it off in from of about 100 people, so it's not a delusion of mine, either.

In his talk, Joshua presented a host of reasons why the BGGA proposal is a really bad idea. The key information here is "BGGA". We all want closures and Joshua is no exception, it's just that the BGGA proposal is like Generics on steroids and if you can't wrap your brain about Generics wildcards, then you won't understand BGGA closures as well.

The code in the proposal doesn't look too bad at first glance:

{int x, int y => x+y}

Unless you try to use an array. If you did "int[] x", you'd get an error because closures are based on generics and generics can't handle arrays or primitives.

But the next example is better to understand why BGGA will add a new level of hell to Java which will be worse than generics:

{int,String=>Number throws IOException} xyzzy;

is translated into

interface Function1 { // system-generated
    R invoke(int x1, A2 x2) throws E;
}
Function1 xyzzy;

Doesn't bother you because you're never going to see this? Well, think again because if you try something that the generics type system doesn't understand, you'll get a generics error message like this one:

NewtonWithClosures.java:26: invoke(capture#418 of ? super {double => double}) in {capture#418 of ? super {double => double} => capture#928 of ? extends {double => double}} cannot be applied to (double)

The reason for this is that the closures are implemented using generics and without any high level support in the compiler so the compiler can't generate a more useful error message. And this was a simple example. We all know how quickly generics get message and for me, that means that any implementation of any new feature that is based on generics is a threat to the future of Java.

Again, I'm for closures and I use them as often as I can in Groovy but the current proposal is just a new way to make Java harder to use. Why don't they simply change the compiler to allow to access field and method objects (from java.lang.reflect) via the class? Like so:

collect(list, Math.class.min)

If we could use Method objects like first class citizens (instead of via the horrible reflection API with it's horde of checked exceptions), we could use Method objects as simple closures. Then, all we would need is a set of util classes for single mutable primitives and we're done. Sure, the syntax wouldn't be as compact but every normal Java developer would be able to understand the concept and how it's supposed to be applied in a few hours.

If you care, here is a link to the whole set of arguments by Joshua Bloch. Read it, keeping in mind that Joshua is pro closure, he just wants to avoid a second generics debacle.

3 comments:

Neal Gafter said...

I'm sure Josh mentioned that his comments don't reflect Google's position, and that his comments apply to an old version of the prototype (pre-October 2007); many of his concerns simply don't apply anymore. I suspect he didn't show you the source code corresponding to the "incomprehensible" error message - his source is much worse than the error message itself; the complexity of the diagnostic was a bug.

Joshua Bloch said...

Hi all.

The new version of the talk has not yet been posted, but it will be posted on Monday on the Jazoon site. The first slide in the talk, which I read it out loud, says this:

This Talk Represents My Opinion, Not Google’s!

“Google believes the Java platform will likely benefit from continued research into closures. To arrive at the best solution, Google is open to multiple parallel investigations but is not currently prepared to commit to any particular proposal. We do not expect these investigations to yield results in time for Java 7, and are of the opinion that it is premature to launch a JSR that forces us down any specific path.”

I mentioned the new prototype several times during the talk, and the last slide in the deck is devoted to it. I do not believe that the new prototype solves the poblems described in the talk. In particular, I believe that restricted closures accomplish little. They're an attempt to fight complexity with more complexity. I don't believe that programmers will remember when to use which of the two "arrows" (==> and =>).

I would have ported the examples in the talk to use the new prototype, but it lacks a spec or a README file. Also I had very little time to prepare the new version of the talk. (I voluteered to give it on short notice when another Google speaker had to cancel.)

Incidentally, the source code that generated the indecipherable error message was not "worse than the message itself." Not even close. It was a straightforward translation of some "finger exercises" from Abelson and Sussman's "Structure and Interpretation of Computer Programs," with an honest mistake. The line that generated the error message wass on the slide for all to see:

  return fixedPoint(transform.invoke(guess));

Regards from Zurich,

Josh

Aaron Digulla said...

Please, stay on topic here, guys. I never mentioned Google in my post, so why did you bring that up? It's a non-issue here.

The key issue is: BGGA is implemented with Generics+Wildcards and I'm pretty sure that 99% of all Java developers agree that Wildcards in Generics were a mistake. We can argue about the amount or how they could be fixed but that's not the point. Most people can use Generics without Wildcards but with them, it either works (and you don't know why) or it doesn't (and you won't know, either).

And if anyone argues that "only the library guys" will have to worry about that, well, none of them work at my company. In my team, I'm the superman and I usually don't get Wildcards to work, not even with the help of Internet search machines. So I think that most other teams also won't be able to cope with that, either.

Bottom line: IMO, the BGGA approach is history repeated. As long as the prototype is based on Wildcards, no matter how far they is hidden from the developer, I urge any Java developer who cares about the language to give this prototype a thumbs down.

Groovy and Scala have shown that we can have closures which don't ruin your day, so that's where I would put my money in.