Hacker News new | comments | show | ask | jobs | submit login

The top priority is still to avoid confusing programmers, and closing over non-final variables can lead to some very confusing situations. For example:

List list = Lists.newArrayList(); for(Integer i = 0; i < 10; i++) { list.add(fn [x] { i + x }); }

Think you just created a list of 10 functions that each add a different number to their argument? If you closed over the i variable, that variable changed and by the end of the loop is 9. All of the functions return their argument plus 9.

In any case, I can't wait to get some form of closures in Java. Best case would be to get a job using a decent programming language, but closures and various data type literals could go a long way to dull the pain until then.

This certainly does appear to be a common point of confusion for languages that have both mutable variables and closures:

http://stackoverflow.com/questions/271440/c-captured-variabl... http://stackoverflow.com/questions/233673/lexical-closures-i...

I remember bumping into the issue myself in JavaScript, but only once. After I became aware of the concept, it was never a problem again, in any language. Those one-time issues don't worry me. It's the problems that come up over and over again that are worth fixing at the language level.

A good way to explain it is to analogize captured variables to variables used in the body of a loop or conditional. Variables are only ever created when a declaration is evaluated, and a variable has exactly one value at any given time. The obvious alternative, copying the variable when it's closed over, seems more confusing to me. And the current restriction, that captured variables are final, is just going to force hackery.

Ultimately, if Java grunts want closures, they will have to understand variable capturing. It's part of the package.

To me the confusion is more with the loop constructs. My mental model is fine with variable capture in general, but I don't interpret loop variables as "real" variables. What I'd intuitively expect, if I didn't already know that most languages don't do it that way, is that the loop variable is freshly bound on each iteration. That expectation is strengthened by the fact that a lot of languages seem not to want to allow you to actually use it as a real variable anyway: you often can't modify the loop variable within a foreach-style loop, which leads me to view them as fresh immutable bindings per iteration.

Admittedly, the Java for loop is a plain C-style for loop, where you actually can modify the loop variable if you wish, so it pretty much has to work that way. But the binding-reuse behavior of, say, Python's for i in range(n) loop makes less sense to me. IIRC, it's also one of the many contentious differences in Common Lisp between the LOOP and ITERATE macro packages.

Ah yes, it is a problem if a language is not clear about the lifetime semantics of a loop variable.

In Ruby, for example, an idiomatic loop like 10.times{|i| ... } does indeed bind a new variable for every iteration, but that is implicitly clear to anyone with a basic understanding of the language. Likewise, the 3-part for loop of Java et al does not hide the fact that it's the same variable every time through the loop.

The Java for-each loop, on the other hand, is more ambiguous. A quick check seems to indicate that the iterator variable can be declared final and captured in an anonymous inner class. That means that for-each acts differently than for loop and I could see that confusing your average code monkey.

Yeah, I think the main thing that's confusing about the particular example given in this thread is that the common case of looping over integers usually intends a foreach-style loop, but Java syntax doesn't make it easy to do something like for(final int i : Range(1,10)). So people end up using the C-style 3-part for loop when they don't have any real need for its power.

I actually think that will change in Java 7. I will likely not be using "for" very often, and will start using higher-order functions like map and fold. The issue is mainly developers for whom closures are a new concept. If they are too confused as they make their first nervous steps into the world of functional programming, if their first attempts at using closures result in a lot of bugs, then they may write off the whole thing as more complicated than it's worth.

Applications are open for YC Winter 2018

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