Yes, I saw that argument coming. That's why I cited Paul Graham in that blog post:
“When a function refers to a variable defined outside it, it’s called a free variable. A function that refers to a free lexical variable is called a closure.”. Paul Graham, ANSI Common Lisp, Prentice Hall, 1996, p.107.
Thus, lambdas without free variables are no closures. I also mentioned the single-element-array trick in my blog:
int sumArray[] = new int[] { 0 };
ints.forEach(i -> {sumArray[0] += i;});
println(sumArray[0]);
Nevertheless, it is ugly.
Kotlin performs the work-around automatically for you and I appreciate
that, but that doesn't mean Java's lambdas aren't closures.
I'm not sure about this. The Kotlin guys are bound to the JVM, but this does not prevent them from allocating closure variables on the heap so that they become visible when declared in a context that is an outer context to the closure expression. But I better hold myself back here and let the masters themselves comment on this ...
Here is a really good thread where even Neil Gafter himself tried to explain why inner classes in Java are no closures: http://www.theserverside.com/news/thread.tss?thread_id=57148 The reasoning from Neil Gafter makes me guess that Sun initially had in mind to implement true closures. But that is pure speculation…
There's a very good reason for this (multi-threaded execution without surprises)
This is an interesting point and I tried to talk about it with the Scala guys on their forum for some time ago, but there was no interest. In Java this also doesn't work as the read-only behavior of a final variable can be by-passed with the mentioned single-element-array trick, which is admittedly only true in case the initial developer declared an array, but in many cases the closure variable is often a nested object just like the single-element-array.
Also, Java 8 lambdas are not implemented with anonymous inner classes
under the hood. They compile to method handles, so there's no
instantiation overhead.
All right, I see. Thanks for this one.
– Oliver