The confusion about closures happens because it doesn't exist in other languages. (There isn't a way to express it.)
Let's look at a simple C function that uses a global variable:
int a = 1;
int a_plus_2() {
return 2 + a;
}
This always returns 2 more than "a". Initially it will return 3. If "a" is set to 5 at some point in the future, "a_plus_2" will then return 7. Simple. No closure here.In Lisp, "a" would be called a "dynamic variable" because it changing its value affects all code that uses "a" over time, including usage within other scopes; "a" has a dynamic binding. But Lisp also has static binding which means the value of the variable is captured each time a scope is created and remains static over time within that scope.
Imagine a variation of C where variable make this distinction explicit by prefixing with with <dynamic> and <static>. <dynamic> would be the default and in fact is how the real C behaves. <static> now means Lisp notion of static binding (forget C's notion of static, which is totally different). Let's use it.
<static> int b = 1;
int b_plus_2() {
return 2 + b;
}
So here "b" is marked as static. When "b_plus_2" is defined at compile time, the current value of "b" is captured - statically bound - to its current value of 1. So "b_plus_2" will always return 3 _even if the global variable "b" is later modified. b = 5; /* modifying b */
int new_b_plus_2 {
return 2 + b;
}
Calling "new_b_plus_2" return 7. No surprise here. The twist is that the original "b_plus_2" still returns 3. The value of "b" is captured in a closure. Each new scope encloses the current value of "b", binding its current value statically (unchanging) within that scope. Closures become interesting when the block in question is a function body.So, yeah - it's a simple concept in the end. It's tricky because it doesn't exist many other languages. It provides a way to encapsulate state analogous to an object in OO languages [1].
The concept is more useful in Lisp with its higher order functions - functions that define other functions. This is very fluid in Lisp, while Python uses its lambda form for anonymous functions, Ruby has blocks and lambdas and...[2], and Java gets close with inner classes.
I hope this helps.
[1] "Objects are a poor man's closure" and "Closures are a poor man's object" http://stackoverflow.com/questions/2497801/closures-are-poor...
[2] I'm don't do Ruby - but's here's a ton of stuff on closures in Ruby: http://innig.net/software/ruby/closures-in-ruby.rb