I started out nervous with the idea of adding closures to Java, and I think I’ve slid firmly into the “contra” camp. One reason is that it seems increasingly a bad idea to add anything to the Java language. On a related subject, my brief sojourn in Ruby-land has changed my thinking about closures entirely.

Java and Closures · A good place to start is Bharath’s BGGA closures: The end of many Java careers. Clearly he’s a contra too, but he links to both sides’ arguments.

My argument is simple: Java worked so well because it hit the 80/20 point; for my money one of the loudest, cleanest 80/20 technology victories ever. Subsequent attempts to fill in the 20% were, well, mostly harmless. Until generics, which are a disaster; they have made Java harder to learn and to understand, and you can’t avoid them.

So I’m really scared about trying to chip away any further at whatever’s left of the 20%. Also, I look at the motivating examples for closures and I think that the conventional alternatives aren’t that bad. Also, I look at the proposed code and I think that on balance it’ll make Java harder to read. Also, as Bharath points out, if you really need closures and and functional-programming goo and suchlike, there are at least two excellent Java-platform languages that have elegant, well-tested designs: Scala and JRuby.

But you know, I could be wrong. Maybe there’s a way to build closures into the Java language in a way that’ll add power smoothly with no real downside. If that’s true, we need to discover it and prove it, and the JCP isn’t about discovering things; it’s about the worst possible place to approach this problem. Now that Java is Open-Source, anyone can go cook up whatever loony closure facility they want, and if it’s good enough, people will start using it whether the binary build has “Java” stamped on the outside or not, and then start shouting that it should be in the standard distro, and only then should the JCP consider going near this tar-pit.

My favorite place to start improving Java wouldn’t be with the language at all, it’d be the Multi-Language VM project. The motivating use-cases for that aren’t theoretical in the slightest, they have names and addresses and are screaming for love.

Ruby and Closures · Ruby calls ’em “blocks” and you basically can’t write any code without ’em. When you first see how they’re used, you think “Hey, that’s a nice clean way to do iteration”. Then when you want to write one of those functions, you dig in and find out about yield, and you nod your head “of course”.

They have to be closures because they look like (and are) chunks of code embedded in your classes and methods, which can naturally use those classes’ and methods’ variables. So there’s nothing in the slightest strange or surprising.

Later on, when you get a little deeper into Ruby, you find out about &block arguments and procs and lambdas, but by that time you’ve internalized the notion that a few lines of code have an independent life even if they don’t have a name, so the mental effort in figuring it all out is about zero.

But even in Ruby, to my eyes the most readable of languages, code that uses procs and lambdas is often hard to read. (Code that uses ordinary blocks is trivial to read, the closure-ness is implicit and invisible).

And at the end of the day, the number of times an application programmer is going to really need a proc or a lambda, to the extent that it’s a win to suck up the readability cost, probably isn’t that high. Yes, it happens; I’ve done it myself. But as I said, not often.

Conclusion · Sorry, I don’t have one. Ruby proves that it’s possible to get closures right and make them accessible to grunt programmers. But if they’re going into Java, they need to earn their way and be field-tested in the open-source ecosystem first.



Contributions

Comment feed for ongoing:Comments feed

From: Simon Willison (Dec 17 2007, at 00:33)

I think JavaScript is potentially a more interesting case study for closures than Ruby is, mainly because JavaScript is becoming unavoidable for anyone who is developing applications for the web, no matter what server-side technology they use. Closures are pretty much essential if you want to write maintainable, concise JavaScript because the entire development metaphor is based around callback functions, which are a sweet spot for using closures.

That doesn't make it any easier to explain them though. In fact, GWT appears to exist principally to protect Java developers from having to figure out closures.

[link]

From: W^L+ (Dec 17 2007, at 00:37)

Java has already become one of those "Ugh!" languages, a dishonor it shares with C++.

It is very powerful, but extremely verbose (like COBOL!) and full of "you can't do that, but if you do X, we make an exception".

I'd love to see a Java _replacement_ with a simplified syntax that removes the verbosity and repetition and runs on the JVM. Rationalize the standard libraries, too, and continue to update the Unicode support. I think Scala is a good start, but it needs just a hint of Smalltalk.

[link]

From: David Moles (Dec 17 2007, at 01:02)

Josh Bloch just premiered that talk at JavaPolis in Belgium, and I came out of it convinced that the BGGA approach is a bad, bad idea. He wasn't convinced that anything was actually needed either -- and also suggested that what we need is some working implementations to play around with before we do anything irrevocable like float a JSR.

But have you looked at his (and Doug Lea's and Bob Lee's) CICE proposal (http://docs.google.com/View?docid=k73_1ggr36h)? It's fairly small and simple, it's Java-like, it's about removing rather than adding, and (as someone who's typed "public void run()" and "public void actionPerformed()" a few times too many) I know it'd make *my* life easier.

[link]

From: Mark Evenson (Dec 17 2007, at 01:12)

Tim Bray writes: "there are at least two excellent Java-platform languages that have elegant, well-tested designs: Scala and JRuby".

And, of course, almost lost in the thickets of history, there is Common Lisp, where closures may be said to have originated and therefore certainly qualifies as a "well-tested" case, and "elegant" to my eyes.

Armed Bear Common Lisp

http://armedbear.org/abcl.html

[link]

From: Justin Mason (Dec 17 2007, at 03:59)

It's worth noting that Perl similarly makes closures accessible to "normal" programmers; one can simply refer to lexically-local variables declared outside a sub { ... } scope, within that scope, and it "just works". Totally intuitive and automatic.

Over the past year or two, closures have been top of the list of new techniques which have revolutionized my coding style; I now have a hard time dealing with languages that don't support them.

[link]

From: Kaur Jaanson (Dec 17 2007, at 05:27)

Groovy (http://groovy.codehaus.org/) also gives the ability to use closures with Java, and has java-like syntax.

For some reason I didn't like ruby-s syntax (maybe I was too lazy to learn, can't remember)

[link]

From: she (Dec 17 2007, at 06:21)

"But even in Ruby, to my eyes the most readable of languages, code that uses procs and lambdas is often hard to read."

I agree wholeheartedly.

Ruby as a language (for me, when I write) is the cleanest language so far, but this does not mean that other writers do not produce unreadable code (for me).

Everyone has a different style, and the more features a language offers, people will use it.

That can be both good and bad. For me, I concentrate on the smallest subset to achieve a certain goal i.e. I avoid @@class_vars whenever possible etc..

[link]

From: Marcus (Dec 17 2007, at 06:35)

Wow, I really can't believe what I'm hearing. Basically what it comes down to is too many people saying that (1) Generics are bad, and (2) Java programmers don't need closures even though, and this is important now, Every Other Major Programming Language In Regular Business Use Has Them (or something like them).

Wow.

1. Generics aren't bad, they just had to be shipped with a well known flaw which makes them less valuable up front: Erasure. It is conceivable that Java 7 could remove this limitation since presumably byte-code compatibility is not expected for the next major JVM version.

The argument that Generics are too complicated or whatever are disingenuous at best. It doesn't take much mental exercise to realize they are extremely valuable to a preferably small and yet very important segments of the developer population: framework writers and library writers.

Sure, everyone and their brother ends up creating frameworks where there should be none, but don't shoot the messenger. Nor should they really be derided that badly anyone, after all, its in this organic culture that innovation occurs.

2. Every other major language in use has closures or something close enough to them. Why Java should be without them is beyond me. I yearn for them frequently. Aren't you one of the many people who believe that programmers should learn a language every year? Well, they did, and they came back with functional ideas. And they thought to themselves, "why on earth are we doing it this way, when we should be doing it that way?"

This is tripe, and basically its the old guard still trying to muscle in and hold back Java. Fortunately your employer is a changed company, and clearly the leadership of Java internally at Sun has been seriously shaken up, sometime in the past 2 or 3 years, and my money is on Rails (not Ruby) as the catalyst. A bunch of designer types realized they could be automating their chores, and Rails was born. And suddenly Java had to work for its programmers instead of its programmers working for it.

Now if you people who don't want to use Closures and Generics could just quiet down a bit and go back to using Ruby, then we could all benefit a lot from the work of the new guard. This IS the organic growth of Java.

Finally, your statement that this stuff only rightly happens by field testing in the open source community is utter over-simplification. These changes are coming from the "community". Anyone can, and they do, make downloadable runtimes to try this out. And you're clearly ignoring the way the leadership of Rails, Ruby, Linux, Perl, Python, Hibernate, and many many more extremely successful open source projects exerts control through benevolent dictatorship.

People who complain so much about the JCP should just chill out a bit and realize that the "benevolent dictator" for Java is Sun, and if they don't like it then they can just go let DHH, Matz, Torvalds, Wall, or Rossum be their Hussein, Bush, Pol Pot, or Putin instead.

[link]

From: AT (Dec 17 2007, at 06:51)

Tim,

Not sure about your point regarding how generics are a disaster!

The alternative, which you think isn't that bad, which is anonymous inner classes, is so hard to read generics seem like a Godsend! I work with junior programmers most of the time, and while generics seem alien to them, once they understand they "why" and "how" they start even overusing it coz all of a sudden they know exactly what to expect from a collection and so forth.

I yet to see a junior programmer who understands anonymous inner classes. And I've seen many examples of senior java people who scratch their heads in bafflement trying to read code containing such constructs.

Closures are an extremely powerful concept regardless of language, and I believe they could actually add to the 80/20 rule you mention positively.

Check out this presentation on the subject by Neal Gafter from Google:

http://www.parleys.com/display/PARLEYS/Closures+for+Java

[link]

From: Marcus (Dec 17 2007, at 07:13)

I have to add, your term "grunt programmers", which is more or less the same feeling I get from most of the people arguing against programmers, is an oddly aristocratic and demeaning way to describe both your and my profession.

[link]

From: Dalibor Topic (Dec 17 2007, at 07:48)

I'd rather see someone take a good luck at Java, and write the next big C family language fixing its weaknesses, than to see more stuff being piled on a structure that was not made for that. The 'extend the libraries, not the language' philosophy of the early days worked pretty well, because the language does not have that much flexibility for major extensions when all the necessary constraints of the interaction with existing features have to be considered.

It's much easier to start from a plain field, with the lessons learned. It may even be better to start out with the MLVM JVM, than to target the lowest common denominator.

[link]

From: Kevin (Dec 17 2007, at 10:24)

Oh come on, if C# can /elegantly/ introduce Generics and Delegates in 2.0 and now LINQ in 3.0 (with no MSIL changes!!), surely Java can do the same. It's just syntactic sugar. Give us sugar! Please!

[link]

From: Sebastian Good (Dec 17 2007, at 11:20)

Wow; I think you'll look back on this in a year and be a bit embarrassed by what you've written. You seem to be saying "I can't think of good ways that closures would clean up Java code, therefore we should leave it out." Well, perhaps that's just because you can't think of them!

[link]

From: Dave (Dec 18 2007, at 02:40)

Sebastian Good thinks you're saying that you "... can't think of good ways that closures would clean up Java code, therefore we should leave it out." and responds "Well, perhaps that's just because you can't think of them!"

Yes, I think that perhaps is exactly your point.

"Don’t EVER make the mistake that you can design something better than what you get from ruthless massively parallel trial-and-error with a feedback cycle. That’s giving your intelligence _much_ too much credit.

— Linus Torvalds

[link]

From: Pierre Phaneuf (Dec 18 2007, at 08:13)

I agree with Justin, above. It *can* be easy to use, all of Perl, JavaScript and Ruby are good examples of that, and I don't know about you, but while we're going multithread-happy, there's still a bunch of things that are quite event-driven in our programs (GUI events, timers, etc), and it's just so easy to go with something like "add_timer(5000, sub { $self->plonk(); });" in Perl, say.

[link]

From: Paulo (Dec 18 2007, at 11:28)

Python is moving away from higher order functions (that use closures and method pointers, normally with yield inside eyech) to Generators (that evaluate lazily by default, probably with a hidden implicit yield. All that whoopla about the nature of return inside a closure is not more than a hidden yield (with the exceptions complications added). If you want to make custom for constructs i'd HIGHLY, HIGHLY advocate that we look at python generators.

Do you know why they are moving away from higher order functions. Because they get hard to read... Now add Generics and types like in java. The result is not pretty for me.

[link]

From: Brennan (Dec 28 2007, at 11:55)

I heartily concur that Ruby does closures in a much easier way than any of the currently proposed closure additions to the Java language. I think that this is because it is much simpler to do so in a dynamically typed (or at least inferred) language. Maybe closures in Java are best left to scripting languages that target the JVM, such as JRuby, Groovy, and JavaFX Script.

[link]

From: Stephan (Dec 29 2007, at 00:31)

We've just published the JavaPolis presentation of Joshua Bloch on the Closures Controversy @ Parleys.com ... you might want to see this :)

[link]

From: rmlinden (Jan 07 2008, at 01:44)

Sorry to say so, but i kinda have the feeling you missed the point or not clearly understand what generics and closures are about.

And yes im probably saying something really stupid here.

A second thing that bothers me .. I understnad things should be readable, I understand that code should be understandable. But programming IS complex. In essence its mathematics where we take data from a domain and we use a function or a relation to map elements from one domain to a codomain regardless of where it is present (java memory, the html of a page, a database).

anyhoo back to generics

Programming languages are often typed. Java is a strongly typed language. If you make a Person object you know its a Person and not a Car.

Certain methods operate on a Person, they have nothing to do with a Car.

But why then are there generics. Generics are simply there to write code that doesnt care about a type. It doesnt care if it operates on a Car, a Person or Dolly Parton. But why then generics ? If type isnt important why then dont use Object ? Well Object isnt strongly typed. Generics are. Well the should be.. unlinke the Type erasure that java performs.

All in all generics allow a programmer to write code that doesnt care about WHAT it manipulates as long as its strongly typed.

Say i want some code that puts apples into bags. and later on I want some code that puts gas into a car. Then a method that stuffs pencils into a pencilcase. Normally that would mean 6 types (car, gas, pencil, pencil case, apple, bag) and 3 separate methods apple->bag, gas->car, pencil->pencilcase.

With generics you would get 6 types also and ONE generic method to put some THING into another THING. Where the second is something that can contain other things.

public void add(I element, O container){

container.add(element);

}

This add method essentially is a closure. As long as container is not null and it doesnt throw exception or other side effects its a closure on 2 bound variables element and container.

Its not hard, its just a concept.

----------------

Programming is about mathematics. Its about sets and subsets, relations, domain to codomain transformations, intersections of collections using certain predicate conditions, its about sideeffects and closures.

In essence these features need to be provided to a programmers if there is a need. Yes it may not be easy to understand, but then you allways have the option to add all kinds of methods and apis that are more easy to understand for people who have difficulty understanding those features.

Thing is .. all that sugar can be implemented in terms of the abstracter methods, not the other way around.

[link]

author · Dad · software · colophon · rights
picture of the day
December 16, 2007
· Technology (77 fragments)
· · Coding (98 more)
· · Java (123 more)
· · Ruby (93 more)

By .

I am an employee
of Amazon.com, but
the opinions expressed here
are my own, and no other party
necessarily agrees with them.

A full disclosure of my
professional interests is
on the author page.