Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Understand closures (christian-fei.com)
38 points by christian_fei on Nov 9, 2013 | hide | past | favorite | 30 comments


I don't think that I really understood closures until I took Dan Grossman's Coursera course "Programming Languages." In it, we implemented in Racket a simple programming language which included closures, which is the point where it really clicked for me.

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...)


That's a good concise explanation. The book "High Performance JavaScript"[0] also does a good job explaining how closures work, and includes some visuals that really hammered it home I thought.

[0] -- http://shop.oreilly.com/product/9780596802806.do


A thing that also really helped me I found in a footnote of Functional Javascript. There the idea of a "free variable" is presented not as free as in freedom, or even free as in beer. But free as in escaped. The variable hitches a ride in the closure and is no longer jailed in its defining scope, and lives on much longer than it normally would.

I found that to be a really valuable shift in the way I processed the phrase "free variable".


thanks for the notes!


No problem, thanks for the blog post! I'd highly recommend taking the course - even with a traditional math/cs undergraduate degree from a good school, it was one of the best courses I've ever taken, both in terms of execution and the amount that I learned from it.


awesome, will do!


The approach Java takes to closures, for all its faults, makes it so much easier to avoid this kind of accident without having to double check all your closures every time.

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.


> 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.

"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).


Yes, final is only 'shallow immutability' and only ensures that the reference itself is immutable. This is the only part that applies to closures though: the reference that is accessible from the closure.

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.


I come exactly from this background at school, so I never had this 'problem' with Java.

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


Yes, spot on.

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-...


never got that much into Java though


Closures are simpler than that. All that a closure does is capture an enclosing environment, and then be able to refer to variables from it later.

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.


i came to the conclusion that functions === closures.

closure/functions close the parents scoped variables in an own scope


That conclusion is language dependent. When you learn other languages, you'll encounter ones like eLisp and C++ which have equivalents of anonymous functions, without making them closures.


ok. but at least in javascript this mysterious phrase is true, right?


Yes.

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.


I don't believe this is "the most practical explanation of closures out there" as the author claims, but it does present a use-case. The most important thing to grasp if you're fussed about naming concepts in JavaScript is the difference between a function, a scope [1], a closure [2], and an IIFE [3].

[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...


thank you, I'm really confused about naming concepts in JavaScript because one time you read something, and a minute after on a stackoverflow thread you find it explained and named differently. but I will read through the links you posted, appreciate that


"This works because functions create an own scope for the variable"

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


updated. thanks for the clarification


This might as well be titled "Understand mutable variables (and function-scoping)".

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.


What's wrong with mutable variables and closures? I 'seal' the variable value 'i' into a closure, isn't that a good example for a closure? I repeat, I wrote this to get constructive feedback, so thanks, and I would like to discuss this further


What is the best definition of a closure?


Decent short explanation. If anyone would like an exhaustive explanation, I'd recommend comp.lang.javascript's FAQ[1].

It's overkill to if you just want a working definition, but is instrumental in understanding the underlying concepts that power closures.

1. http://jibbering.com/faq/notes/closures/


thank you, will read through the notes.

PS: can we say that functions === closures?


Not to be a hater, but the examples on the blog post are insane. Why would I write code like any of those?

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...

[2] https://leanpub.com/javascript-allonge/read


I knew I would get some negative feedback, but that's the whole point of having posted it here: to get feedback. I came across this problem and found a possible solution like closures worked fine. I was just trying to get my head around closures, because that's the only thing that I found useful for this particular use case. Anyways, thanks for your feedback, much appreciated!


The behavior of the "I don't believe you" buttons was only slightly annoying, but then I made the mistake of clicking the "now i do" button, too. :)


lol




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

Search: