Understand closures
christian-fei.com
christian-fei.com
In the class, he defines a closure as follows:
"We have said that functions are values, but we have not been precise about what that value exactly is. We now explain that a function value has two parts, the code for the function (obviously) and the environment that was current when we created the function. These two parts really do form a “pair” but we put “pair” in quotation marks because it is not an ML pair, just something with two parts. You cannot access the parts of the “pair” separately; all you can do is call the function. This call uses both parts because it evaluates the code part using the environment part.
This “pair” is called a function closure or just closure. The reason is that while the code itself can have free variables (variables that are not bound inside the code so they need to be bound by some outer environment), the closure carries with it an environment that provides all these bindings. So the closure overall is “closed” — it has everything it needs to produce a function result given a function argument."
(section course notes: https://d396qusza40orc.cloudfront.net/proglang/lecture_slide...)
I found that to be a really valuable shift in the way I processed the phrase "free variable".
Java only allows 'final' or immutable variables to be passed into closures. This prevents the value from changing and ensures that the compiler catches the problem if you try to pass a changing value into a closure.
It was pretty new to me and kinda not sensed the concept behind closures.
I would like to know what you think about the explanation I provided in the post about closures. Did I get the point? Don't hesitate to tell me if I'm totally wrong
For your original code example, the Java compiler would have failed with an error that the variable 'i' was not declared final (immutable). Java 8 supports lambdas now, but in earlier Java versions you would have had to add a line like 'final int fi = i;' and you could then have used the fi inside the closure. The point in my previous post that the compiler detecting this ambiguity is exceptionally helpful and I'd prefer more languages to follow that route.
With Java 8 lambdas, it's much the same but with some nice syntax to make it easier[1].
[1] http://java.amitph.com/2012/08/at-first-sight-with-closures-...
"Final" in Java does not make objects immutable. The object itself can have mutator methods that change instance variables/attributes of the object, even though the identifier is declared as final.
IIRC, the only reason Java requires variables in closures to be final is for garbage collection. "final" allows the runtime to know that the identifier itself isn't going to be rebound to a different object, which is different from knowing that the object that it is being bound to won't change internally.
(Disclaimer: It's been a while since I used Java proper, so I'm probably missing some subtlety with the explanation of the rationale, but I'm pretty sure it's something along these lines).
Full immutability is left up to the programmer / api designer as with javascript - as it should be, imo. Trying to optimize fully immutable data-structures when performance becomes an issue in an inner loop down the line is a nightmare I would not recommend.
To try to put a name on what you've observed, what you're really doing is emulating a call-by-name [1] evaluation strategy, in which you want an expression to be evaluated at the time the asynchronous callee needs the value, rather than when the call is scheduled. Some languages (like Scala) have specific syntax for this, but in other languages, you emulate this behavior by wrapping the expression in a function, and calling that function when you want the expression to be evaluated.
The closure facilitates this by letting you bind names in the expression to variables in the outer scope. These variables aren't available to the actual caller of the function (somewhere in setTimeout's implementation) to be bound to the function's arguments in the "normal" way. So really, you find that there are two basic ways to make variables available to a function's scope: the invoker of the function can bind the function's arguments to values in its scope, or the function can bind variables from any of the scopes that enclose it, namely all of the enclosing functions. (There's also `this`, but that's another story.)
A much better use case is if you want an event handler to have access to the state of the object that registered it. If you bind the event handler within that object's scope, you can refer to that state within the event handler, and whenever it fires, the current value of state will available from the enclosing scope. This comes up all the time for me when writing Backbone apps. When doing this kind of stuff, be sure to understand thoroughly how Javascript's `this` works (ugh...).
Also, when designing recursive algorithms, closures give the innermost nested layers of your algorithm access to variables from outer scopes, reducing the need to awkwardly pass in parameters that don't change between inner function invocations.
Closures are just the tip of the iceberg. Other concepts like higher-order functions, decorators, and combinators are also really powerful. I highly recommend the most excellent Javascript Allongé [2] for anyone who truly wants to understand this stuff, and learn how to really make it work for them.
[1] http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_nam...
All of the confusion in JavaScript comes from the fact that the enclosing environment is generally bound to the nearest function call. This is not what people expect, and it is not what happens in other languages with closures.
If versioning JavaScript features was not such a mess, it wouldn't happen in JavaScript either. Everyone would learn to declare variables with let instead of var, and closures would just work sanely. Unfortunately you need to use JavaScript 1.7 to get that feature, and browsers assume that you're using JavaScript 1.5 unless you jump through hoops to get there.
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/New_... for more.
closure/functions close the parents scoped variables in an own scope
But it is one of a set of mysterious phrases like "pass by value" and "pass by reference" which, if you learn them, will make it much easier to keep multiple languages in your head.
[1] https://developer.mozilla.org/en/docs/Web/JavaScript/Referen...
[2] http://unscriptable.com/2011/10/02/closures-for-dummies-or-w...
[3] http://benalman.com/news/2010/11/immediately-invoked-functio...
It works because it's a brand new variable. JavaScript is a pass by value language, and the i inside the function is a different chunk of memory than the i from the loop
The post doesn't really explain closures, and the examples really just show what happens when you mutate variables, in this case in a for-loop - they change value!
The last example also shows how javascript has function scope as opposed to block scope, i.e. the variable "string" might as well have been declared outside the for-loop.
It's overkill to if you just want a working definition, but is instrumental in understanding the underlying concepts that power closures.
PS: can we say that functions === closures?