Hacker News new | past | comments | ask | show | jobs | submit login
Java Closures after all? (puredanger.com)
54 points by fogus on Nov 18, 2009 | hide | past | web | favorite | 28 comments

Don't forget that Java already has anonymous classes, which can be used to mimic closures.

I taught my advanced compilers class how to compile Scheme directly to Java by using them to implement lambda:


In fact, as the link above points out, anonymous classes are flexible enough to express the Y combinator, allowing "recursion-less recursion" in Java.

While technically correct, using anonymous inner classes makes code more verbose. Closures are a more elegant solution.

If you look at it that way, anything from generators to continuations can be 'simulated' using enough layers of class definitions.

Apparently the closures will be based on the FCM (first class methods) proposal be Stephen Colebourne:


First-class methods would be a win, but the syntax leaves a little bit to be desired. Closures would be much more of a syntactic eyesore if they A) had context-based type inference on the arguments, so that if I'm passing a closure to a method that expects (String, String) -> as its type I don't need to redeclare the variable types and B) allowed for embedded expressions rather than requiring them to be full function definitions with a "return" statement in there. Unfortunately, the FCM proposal doesn't allow either of those.

To use their example, it should be much more like:

Collections.sort(list, \str1, str2 -> str1.length() - str2.length());

instead of:

Collections.sort(list, #(String str1, String str2) { return str1.length() - str2.length(); });

There's no technical reason you couldn't do the former in Java (and their proposal seems to infer the return type just fine?), but no one involved with the Java language seems to really value conciseness.

Neal Gafter has updated his java closure info page with the infromation from Mark Reinhold's talk.

http://www.javac.info/closures-v06a.html http://www.jroller.com/scolebourne/entry/closures_in_jdk_7

Maybe I'm missing something here: but what's the point of closures without functions as first class variables?


Scroll down to method literals

Why do you assume they won't be first class? We really have very little details at this point.

Deferred execution is a pretty big win for a lot of problems.

Something tells me these are going to be as bad as PHP's closures; you can't just tack on lambdas at the last minute, it has to be part of the language design initially (no?)

As someone who's implementing closures in a JVM-based language, I can tell you there's no technical limitations on the JVM side: there are decisions to be made as to how you want to implement them, but it's certainly doable with enough compiler magic.

That said, the BGGA proposal is a bit of a disaster in my opinion: the distinction between "restricted" and "unrestricted" closures, along with non-local returns, just makes no sense. My assumption is that they want to use closures for things like control structures, which they're just totally inappropriate for, rather than as just anonymous functions, which is what they really ought to be.

Basically, it's what they did with generics: take a relatively sensible concept, then add a bunch of baroque edges to it for no good reason. Honestly: => and ==> are almost equivalent things with totally different semantics as far as control structures? Really?

People are going to understand that about as well as they understand why they can't add an Object to List<? extends Object>, or why they can't pass a List<String> back from a method that says it returns List<Object>. By which I mean, not at all.

The design principle behind Java is "don't add features that could confuse programmers". (This confuses me, a programmer, but that is a bit too meta for this post.)

Despite this principle, Java's users asked for generics, and so the language designers added them. But with a twist; they intentionally made the simple concept very confusing. This is so that the next time someone asks for a feature, they can point at generics and say "look at how badly we broke that! do you really want us adding more features?" A few episodes like this (closures will be next), and people won't ask for features anymore. With no more feature requests, it will become clear that Java Is Perfect, and the designers can retire with a very smug feeling of self-superiority.

I think.

The info is sketchy at this point but it seems that Stephen Colebourne's First Class Method proposal is the one in the running.


"That said, the BGGA proposal is a bit of a disaster in my opinion: the distinction between "restricted" and "unrestricted" closures, along with non-local returns, just makes no sense."

The BGGA proposal was recently updated: "The concepts of restricted and unrestricted function types and closures have been removed. Now, all lambda expressions are restricted. The equivalent of the previous specification's unrestricted closure may be passed to a method by using the control invocation syntax."

It is rumored that it is something like a compromise between the BGGA and the FCM proposals that Sun is pushing.

C# got them in version 2.0 and most people think that's a pretty spiffy implementation. Even more-so with the sugar added in 3.0

Not true in general. PHP just did it wrong, because the designers don't really know much about programming languages.

Python had them tacked on after the fact (version 2.0 as I recall, or was it 2.2?), they work pretty nicely IMO, as long as you treat functions as first class objects the whole time you're ok.

Not really. For one thing, you can't modify the closed over values unless you manually box them in a list, due to scope ambiguity. (This may be fixed in 3.0.) It's a little thing, but it makes code that depends on manipulating closures pretty ugly, discouraging their use.

Scheme avoids the issue by having a non-ambiguous syntax (a big advantage of those parens), and Lua avoids it by defaulting to global scope* unless you declare them with "local", which also anchors their scope unambiguously.

* Which is actually not a big deal - the global table is just another table, so you can hook its set method to catch unexpected globals (see strict.lua). It's far less trouble than Python's solution.

Python 3.0 introduces the nonlocal keyword which allows you to assign to closed over names.

Python lambdas do not work well, in fact they can only be one line long. For some cases this may be ok, especially if python was were the programmer learned about lambdas, but from those who come from with languages with real lambdas it is quite limiting.

We aren't talking about lambdas, we are talking about closures. Lambdas are simple syntactic sugar for a function definition that has a single expression, closures are a concept to capture the outer scope.

they work pretty nicely IMO, as long as you treat functions as first class objects the whole time you're ok

Clarify this? Also, isn't there some inconvenience due to the indentation thing?

There's no inconvenience, it reads pretty normally, for example: http://code.djangoproject.com/browser/django/trunk/django/vi...

I meant lambdas in particular. Example is too long for a discussion specific to lambdas.

Someone correct me if I'm wrong, but, I think it was less of "tacking on closures" and more of getting the lexical scoping issues right.

i.e, there was issues with scoping that had nothing to do with closures per-se. When they fixed it, closures automatically became possible.

PHP's closures are abhorrent. The syntax is partly the problem but also the fact that functions aren't first class objects in PHP.

The proposed system at http://javac.info/ is a little weird and unconventional but it could be promising. It really all depends on what Sun/Oracle decides to do with the language as JDK7 seems to be in limbo at the moment.

Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact