Jesper de Jong is a senior Java developer at Logica in the Netherlands. Jesper has posted 1 posts at DZone. View Full User Profile

Closures for Java. Is it Really a Good Idea?

07.03.2008
| 5070 views |
  • submit to reddit

There's a very good article on JavaWorld by Klaus Kreft and Angelika Langer (the latter is the author of the well-known Java Generics FAQ) with the title Understanding the closures debate. I heard about this article on JavaPosse episode 194, and it's also being discussed on Artima.

I knew that there were proposals to add closures to Java, but I hadn't yet looked into the details of the proposals. The article explains very clearly what closures are exactly and gives a good overview of the three main proposals that there are today: CICE + ARM, BGGA and FCM + JCA. Read the article if you want to know what the alphabet soup means exactly. In short:

 

  • CICE + ARM, proposed by Joshua Bloch and others, is not much more than a new, shorter syntax for anonymous inner classes.
  • BGGA, proposed by Gilad Bracha, Neal Gafter, James Gosling, and Peter von der Ahé, is the most ambitious proposal and almost makes Java a functional programming language.
  • FCM, proposed by Stephen Colebourne and Stefan Schulz, also adds functional programming paradigms but doesn't go as far as BGGA in some aspects.

 

What's so controversial about adding closures to Java? Adding any new feature to the programming language makes it more complex. There are people who fear that adding a powerful but complicated feature such as closures might make Java too complex - which means that people will turn away from Java in favour of easier programming languages. This talk by Joshua Bloch from JavaPolis 2007 makes clear how complicated Java could become if BGGA closures would be added.

So, the question is, is it really such as good idea to add closures to the Java programming language? I'm not sure that it is worth the trouble. After reading the article and seeing Bloch's talk, I'm convinced that adding far-reaching closures such as BGGA and FCM will not be so great. What I especially don't like in the BGGA proposal are the non-local returns: a return statement in a closure means you're returning from the method that the closure is called in, not from the closure itself. This makes code very confusing and hard to understand.

I can see how CICE closures would be useful and at least it looks like that proposal is a lot simpler than the other two. But regardless of how much complexity closures would add to Java, there are reasons for me to doubt whether it's a good idea at all to add closures to Java.

Java is an imperative programming language. Because of this, Java programmers generally use an imperative programming style. For example, we write a loop like this

List<String> names = ...;

for (String name : names) {
    System.out.println(name);
} 

Adding closures will encourage a functional programming style, which is completely different from the imperative style. In the functional style, you'd write a loop very differently; you'd call a forEach method on the collection, passing it a closure to execute on each element of the collection (this is what it would look like with BGGA closures):

List<String> names = ...;

names.forEach({ String name => System.out.println(name); }); 

What are the consequences of this? Does this mean that for example there are going to be lots of new methods (such as the forEach() method shown above) in Java's collections API to support this style of programming? That would bloat the collections API. Can you imagine what a mess you would get if you're working on a project with multiple developers where some developers prefer the imperative style and others the functional style?

I'm not opposed to the concept of closures itself, they work very well in other programming languages such as Ruby. The difference is, however, that Ruby has had closures since the beginning, so that Ruby's standard library was designed to work with closures from the start. If (part of) the standard Java library, such as the collections API, which was designed for the imperative programming style, is going to be extended to add support for closures, it will just grow into a complicated and bloated piece of patchwork.

The cost of adding a new feature to the programming language is very high. Millions of Java developers around the world will need to invest time and money to learn the new feature. The authors of the thousands of libraries and frameworks will need to think about the consequences for their products. And closures is not just another minor feature, it will add a whole new programming paradigm to Java. Are closures really worth all that effort? So far, I haven't heard any convincing reason why it would be a good idea to add closures to Java. Sure, they are a cool and powerful feature. But how are closures going to make things easier for me as a Java programmer? I'm not convinced that they are worth the extra complexity and API bloat that they will add to Java.

(Originally posted on Blogging about Software Development)

Published at DZone with permission of its author, Jesper De Jong.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Brian Sayatovic replied on Thu, 2008/07/03 - 7:35am

I'm of the mind that closures should not be added to Java.  Its starting to feel like any time something becomes popular (closures are old, but there wasn't much fuss about adding them since the days of Oak) someone wants to add it to Java.

I've yet to see anyone provide a compelling example of where closures in Java would improve anything.  By declaring formal classes and interfaces in Java, you create your own type hierarchy forming your own domain-specific language.  But with closures, you have these unnamed bits of logic floating about defined purely by their signature.  Is something that takes a Car and returns a Money a loan calculator, a price estimator, or a blue book lookup function?

Even when I've used Java's limited, primitive support for closures -- anonymous inner classes -- I invariably find myself converted it to a non-anonymous inner class or nested class or even top-level class so that I can add more to it (e.g. a useful .toString(), equals()/hashCode(), internal state, etc.)  If you start off with a closure, you've just locked yourself in a little bit more to your typeless bit of logic.

Now I'm no closure expert.  There could quite possibly be some wonderful compile-time or runtime optimizations that could take place when a closure is used that is impossible with anonymous inner classes.  But so far, I'm inclined to make my programs functional and maintainable first, and then optimize when necessary.  If I were to have an inner inner inner loop using an anonymous inner class and found that a closure miht be more performant, THEN I might start clamoring for closure support.  But, it just hasn't happened yet.

Greg Brown replied on Thu, 2008/07/03 - 7:44am

I haven't looked at any of the proposals, but a simpler syntax for anonymous inner classes would be nice. If that's how closures are ultimately implemented in Java, I'd be in favor of it.

 

Michael Hodgins replied on Thu, 2008/07/03 - 8:10am

To me, it seems that the proposals are either pointless (CICE and FCM) or just too overly complex (BGGA). I'm not sure what great problems there are that closures are supposed to fix, but I can't see that saving a few characters of typing is really worth any of this.

 Java was elegant ten years ago; why closures now?

 Michael

Raphael Valyi replied on Thu, 2008/07/03 - 12:04pm

Brian Sayatovic,

you said: "If you start off with a closure, you've just locked yourself in a little bit more to your typeless bit of logic."

Well, this is a pessimistic view I think: why not take it this way: Java will always allow you to state programming contracts by means of types and interfaces. But using closures at the right places, you'll finally have a way to avoid polluting the global type system (and thus bloating the API) with types that are nonsense out fo their local scope (like say an actionlistener or a Ajax call javscript generator most of the time), without the troube of the inner classes limitations. To me, closures actually allow to build simpler code and much simpler API.

Of course this should be balanced with the cost of mixing paradigms and bloating the historical Java standard libraries. Very hard dilememna. On the contrary, if Java don't embrace closusres, the productivity gap between it and say Ruby will keep increasing and Java could simply continue falling in popularity.

So this is a vital question for Java as a language: mutate in some risky ways, or die slowly. The die slowly option seems more comfortable to decision makers since nobody will have much clues to blame them, but people who actually care about saving their Java investment should really be concerned.

Java porbably lost the RIA battle back arround 2002. Now it's already time to make smart move to save Java as a language after 2010.

Still,  I think Java as a plateform will survive a long time, be it with closures or not, given that now if one wants closures Java is a platform of choice to run Ruby (as JRuby) or other higher abstraction langage while keeping using the Java libraries as you need them.

 Regards,

 Raphaël Valyi.

Alex(JAlexoid) ... replied on Thu, 2008/07/03 - 2:51pm

[quote]I'm not convinced that they are worth the extra complexity and API bloat that they will add to Java.[/quote]

A valid concern, but closures are actually there to reduce the API bloat.

Why do you need an interface Comparator just to sort a list of objects? Add closures, remove that API = lighter API.

Though I believe that method pointers or anonymous methods(a.k.a functions) would be a much better idea, but people on the object planet apparently hate functions. And concurrent development would be much easier with functions here and there. I mean you wouldn't need Runnable interface when you just need to do something what does not need to have "internal state".

Brian Sayatovic replied on Thu, 2008/07/03 - 3:00pm in response to: Alex(JAlexoid) Panzin

[quote=jalexoid]

Why do you need an interface Comparator just to sort a list of objects? Add closures, remove that API = lighter API.

[/quote]

Well, yes, a function pointer or anonymous method could do the trick.  But those have no type, only a contract.  There is no type name.  Any function that takes in two Objects and returns an int could then be used in place of a Comparator, e.g. f(o1, o2)=int.  How do you know if that function is actually capable of comparing its two arguments.  Maybe it calculates the difference in serialized size between the two objects.  Maybe it XOR's their identity hashcodes.

Second, I almost always start with an anonymous inner class for comparators.  But I almost always end up breaking it out to a formal class, with a meaningful type name and often additional behavior.  For example, a SalaryComparator might depend upon a CurrencyExchanger to compare international salries effectively.  If I have a closure or an anonymous inner class, that is much harder.  I have to have the dependency in the enclosing scope or make it a globally accessible dependency.  But when I stop saying I have some nameless Compatator implementation and start saying I have a SalaryComparator, I'm imrpvoing the readability and maintainability of the code.

Brian Sayatovic replied on Thu, 2008/07/03 - 3:05pm in response to: Raphael Valyi

[quote=raphael valyi]

Java will always allow you to state programming contracts by means of types and interfaces. But using closures at the right places, you'll finally have a way to avoid polluting the global type system (and thus bloating the API) with types that are nonsense out fo their local scope (like say an actionlistener or a Ajax call javscript generator most of the time), without the troube of the inner classes limitations. To me, closures actually allow to build simpler code and much simpler API.

[/quote]

I don't consider types pollution.  I consider them a way to organize complexity.  Taking away a type name doesn't reduce the complexity, it just makes it harder to identify some of that complexity because it doesn't have a name.  My specific Comparator implementation can have a name, but a comparing closure doesn't.  Yet the exact same logic to compare two value still exists.

Besides, we have access keywords to limit the exposure of types: private, package, protected and public.  If you create your types as private nested classes of your class in question, then no other classes need be bothered by them.

Brian Sayatovic replied on Thu, 2008/07/03 - 3:07pm in response to: Raphael Valyi

[quote=raphael valyi]

Of course this should be balanced with the cost of mixing paradigms and bloating the historical Java standard libraries. Very hard dilememna. On the contrary, if Java don't embrace closusres, the productivity gap between it and say Ruby will keep increasing and Java could simply continue falling in popularity.

[/quote]

 I have never felt my productivity in Java being held back by NOT having closures.  Maybe it's something one can't recognize they're missing until thev'e first had it (FWIW, I use closures in JavaScript quite often).  So I fear this may be a subjective observation.

Brian Sayatovic replied on Thu, 2008/07/03 - 3:11pm in response to: Raphael Valyi

[quote=raphael valyi]

So this is a vital question for Java as a language: mutate in some risky ways, or die slowly. The die slowly option seems more comfortable to decision makers since nobody will have much clues to blame them, but people who actually care about saving their Java investment should really be concerned.

[/quote]

 If Java is insufficient, and there are better languages, why mutate it instead of just switching languages.  People happy programming in Ruby and using closures can continue to use Ruby.  Java doesn't have to add closures so that those envious of Ruby can keep up with the Jones' and stay in Java-land.

In fact, I think by "mutating" Java for the wrong reasons, we're hurting java, not helping it.  We're doing a special form of mutation where we add features but drop none.  So we're expanding it.

What I've not heard yet is a compelling reason for why closures are good for Java.  And every time I hear someone suggest a reason, it sounds subjective.  And no one addresses what you lose with closures: type safety (not signature safety... type safety).

Alex(JAlexoid) ... replied on Thu, 2008/07/03 - 4:02pm

[quote]Any function that takes in two Objects and returns an int could then be used in place of a Comparator, e.g. f(o1, o2)=int.[/quote]

Isn't Java explicitly typed? What is stopping anyone on declaring a function that takes not objects but the cpecific types of objects. in your case

method int compareSalaries(Salary a, Salary b)

 [quote]But when I stop saying I have some nameless Compatator implementation and start saying I have a SalaryComparator, I'm imrpvoing the readability and maintainability of the code.[/quote]

And you are the one talking about API bloat...

 

[quote]then no other classes need be bothered by them.[/quote]

Please see Joashua Bloch's Google Video talking about API design:  www.youtube.com/watch?v=aAb7hSCtvGw

[quote]I use closures in JavaScript quite often[/quote]

FYI: JavaScript has no such thing as closures, just anonymous functions.

[quote]And no one addresses what you lose with closures: type safety (not signature safety... type safety).[/quote]

Type safety is in part due to method signatures, since without them you have no safety at all.
And since when a Map<Integer, String>(not cosidering type erasure) is more type safe then for example ([Integer, String]=>String) - a function or a closure, that takes Int and a String as params and returns a String.

Ray Cromwell replied on Thu, 2008/07/03 - 5:13pm

"FYI: JavaScript has no such thing as closures, just anonymous functions."

Functions declared in local scope close over variables referenced in the local scope. By definition, Javascript has closures.

I'm personally long past the Java closure debate, I don't really care much whether Java gets closures. I want a language with closures, type inferencing, structural typing, and pattern matching. After tasting Scala, for example, Java + closures won't be enough to satisfy me. 

It seems to me that most of the critics decrying closures, functional-style programming, and type inferencing have never built a large project in a language that has them.  Java literally has become COBOL, and should be frozen, while we eventually move onto to something better in the future.

 

 

Brian Sayatovic replied on Thu, 2008/07/03 - 7:58pm

You said: see "Joashua Bloch's" video... It's an hour long... is there something specific in it to look for? I do intend to watch it, but what specifically were you referring to?

Brian Sayatovic replied on Thu, 2008/07/03 - 8:03pm in response to: Alex(JAlexoid) Panzin

[quote=jalexoid]

[quote]Any function that takes in two Objects and returns an int could then be used in place of a Comparator, e.g. f(o1, o2)=int.[/quote]

Isn't Java explicitly typed? What is stopping anyone on declaring a function that takes not objects but the cpecific types of objects. in your case

method int compareSalaries(Salary a, Salary b)

[/quote] Perhaps I misunderstood the closure proposals, but my understanding was that there was no name associated with the closures. My point is that a function signature does not describe function behavior. A type name does not guarantee behavior either, but it can (and should) be used to suggest a behavior. Thus a Comparator does not imply a function that takes two objects and returns an int, but implies an object with a method that can compare to objects and return a relative ordering of them with respect to each other. That is a much more semantically meaningful contract even though the syntactical contract is pretty much identical.

Brian Sayatovic replied on Thu, 2008/07/03 - 8:09pm in response to: Alex(JAlexoid) Panzin

[quote=jalexoid] [quote]But when I stop saying I have some nameless Compatator implementation and start saying I have a SalaryComparator, I'm imrpvoing the readability and maintainability of the code.[/quote]

And you are the one talking about API bloat...

[/quote] I'm not sure what you mean by me talking about "API bloat". Is adding a class API bloat? It depends on how you measure the size of an API. The public contract? The non-private contract? The private parts too? You are still defining part of your program with a closure, just like you are with an anonymous inner class or a fully public top-level class. That comparator, be it a closure to a full class, will still boil down to the same line of code deep inside, e.g. return (salary1 - salary2). The difference, in my opinion, is the semantic contract of where that code is contained.

Brian Sayatovic replied on Thu, 2008/07/03 - 8:17pm in response to: Alex(JAlexoid) Panzin

[quote=jalexoid][quote]And no one addresses what you lose with closures: type safety (not signature safety... type safety).[/quote]

Type safety is in part due to method signatures, since without them you have no safety at all.
And since when a Map<Integer, String>(not cosidering type erasure) is more type safe then for example ([Integer, String]=>String) - a function or a closure, that takes Int and a String as params and returns a String.

[/quote] I think I didn't give a good description (or I'm just plain wrong, but that won't stop me!). What I mean is that you have no semantic safety. Building classes, interfaces, etc. in a language builds up a semantic language. There is a big difference between "salary *= 1.1" and "employee.givePercentRaise(10)". Yes, you are going to be type-safe with closures. But the closure signature provides no semantic meaning. Its English (or whatever you prefer) names we give to classes, variables, methods, etc. that make a program readable, not the primitive types and signatures. Readability is hugely important (see ancient programmer's rule that 90% of a program's life is spent in maintenance). And when you leverage the compiler (and now-a-days, even your IDE) by using not just signatures, but by naming these constructs, you do even better.

Jonas Olsson replied on Fri, 2008/07/04 - 2:31am

I find myself siding with Biran Sayatovic, quite happy with Java "as is".

Jesper De Jong replied on Fri, 2008/07/04 - 3:14am in response to: Alex(JAlexoid) Panzin

[quote=jalexoid]
[quote]I'm not convinced that they are worth the extra complexity and API bloat that they will add to Java.[/quote]

A valid concern, but closures are actually there to reduce the API bloat.

Why do you need an interface Comparator just to sort a list of objects? Add closures, remove that API = lighter API.
[/quote]
But things never get removed from the Java API - they only become deprecated.

It would be great if we could just get rid of old stuff - remove all the deprecated stuff from the API and redesign it with new features such as closures (and generics, enums etc.) in mind. Unfortunately that's never going to happen in Java because Java needs to be backward compatible with old versions.

Alex(JAlexoid) ... replied on Fri, 2008/07/04 - 3:33am in response to: Jesper De Jong

[quote]

But things never get removed from the Java API - they only become deprecated.

It would be great if we could just get rid of old stuff - remove all the deprecated stuff from the API and redesign it with new features such as closures (and generics, enums etc.) in mind. Unfortunately that's never going to happen in Java because Java needs to be backward compatible with old versions.

[/quote]

This is why I was referencing Joshua Blochs video. As he states every developer is an API designer.
So I am not saying that Java API will get slim all at once, but your software will have less of classes and API that shouldn't be there at all.

And if we push some comanies hard enough we can force Java to break backwards compatibility once in a while.

And they did break compatibility routinely(these come to mind): Enums, the destroy method in Thread object...

Romen Law replied on Mon, 2008/07/07 - 2:34am

I reckon Java should have closure.

In terms of style, just make it the same as .NET (e.g. C#, closest to BGGA I guess). A great use case of closure is LINQ.

This way, the argument about complexity/learning curve goes away since you can benefit in both worlds now.

 cheers

romen

Jeroen Wenting replied on Wed, 2008/07/09 - 12:20am

if you want .NET style closures, use .NET.

Java should not have them, they'll make the language far too obfuscated for anyone to understand except a few language designers in their ivory towers who pushed to have them added mainly to stroke their own vanity rather than with the good of the language in mind.

There's no need for them, they cause needless complications in languages not designed from the ground up to have them.

Romen Law replied on Wed, 2008/07/09 - 5:56am in response to: Jeroen Wenting

Please be a little open-minded when you post comments.

 Obfuscation is a subjective matter. Who said Java was not designed for closure from the ground up? Have you read comments from creator of Java from one of the sited links in the comments?

True, I am learning and using .NET. With Java experience, c# is really easy to learn. I don't use closure in C# everywhere. So far, mostly in LINQ. There are certain things that each world (.NET and Java) can learn from each other. No need to be xenophobic.

cheers

romen

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.