4 ms·
What are the applications of this distinction?
by hayksaakian 14y ago
What are the applications of this distinction?
- bulatb 14y agoClosures and plain anonymous functions solve different problems. Using one when you wanted the other is a good way to cause problems you don't how to solve if you don't know the difference. The SO thread has some good examples. A common one is using some closed-over value like it lives inside the function's scope and not the parent scope that's shared between the closures, which is wrong if you return another copy of the function and expect a different copy of that value. var problems = []; function ProblemFactory() { this.causeProblem = function(name) { problems.push(name); }; } new ProblemFactory().causeProblem('isolation'); new ProblemFactory().causeProblem('failure'); problems.length === 2; // true Edits: clarity, example code.
- just2n 14y agoA little clearer, consider this example: function sumArray(arr){ return arr.reduce(function(accumulator, value){ return accumulator + value; }, 0); } The inner function here is what we typically refer to as an anonymous function. However, closures can also be anonymous: function sumArray(arr){ var sum = 0; arr.forEach(function(value){ sum += value; }); return sum; } Both of these do the same thing. One is a closure, the other isn't. The only difference is that the closure has a free variable. The answer, in this SO link, says that the function 'f' is not a closure in the first example which isn't accurate. Consider the canonical wrong way to do it: for (var i = 0; i < 10; i++){ setTimeout(function(){ console.log(i); }, 100); } This function here (or rather functions) is anonymous and it is also closed over i because it is external to the function. It doesn't matter that i is global, because this code would behave the same if it were presented in global scope or inside a function somewhere. The fact that you get 10 10s printed is because the variable is manipulated by the loop and every closed function created is closed over the same variable. This answer argues awkwardly that free variables that are global don't count towards being closures.
- hayksaakian 14y agoI'm not sure what your point is. If no line ever told me what a closure was, it'd still be quite clear that problems should have length 2. Could you show an example where making the distinction is not obvious/intuitive and could cause problems?
- pygy_ 14y agoThey are completely orthogonal. Javascript, Lua, Scheme and others implement * first class functions, * anonymous functions, and * closures (via lexical scope), but some languages only implement some of these features (Python, for example has limited support for anonymous functions, and Emacs Lisp used to have the first two, but not the last one). So, in Javascript: function outer() { var closed_over_local = "Hey ya!"; // The variable must be a local in the parent scope. function inner() { alert(closed_over_local); } return inner; } foo = outer(); foo(); // Alerts "Hey ya". Here you can see a named function that is a closure, since it closes over a local of the parent scope. On the other hand, you can have an anonymous function that's either pure, no outer references: [1,2,3].map(function(i) { return i*2; }); ... or an anonymous function that only references globals. AFAIK, these are not closures (they don't close over variables of the parent scope).
- btipling 14y agoEmacs lisp has dynamic scoping which allows functions to modify the variables in a caller's scope, which is horrific.
- lispm 14y agoEmacs Lisp has now lexical scope. Recent Changes: * Lisp Changes in Emacs 24.1 Code can now use lexical scoping by default instead of dynamic scoping. The `lexical-binding' variable enables lexical scoping for local variables. It is typically set via a file-local variable in the first line of the file, in which case it applies to all the code in that file.