Other people have already answered this, but since you come from a C++ background, perhaps this will help.
Lambdas and closures get mentioned together because they don't make sense apart. "Lambda" is just a fancy term for an anonymous function, but it also implies that the function is created (sans optimizations) dynamically (i.e. at runtime). This doesn't ever happen in C++, so hence the confusion.
A closure is the concept that a dynamically created function carries with it the state in which it was created (in C++ terms, the callstack). Imagine for a moment we had a C++ keyword called "lambda" that could create functions at runtime. What would the following code do?
You see the problem? "x" is no longer on the stack once foo() returns, but the function we return from foo accesses it! In fact doing anything meaningful with "x" is bogus. The solution is to have dynamically created functions like this to logically copy the call-stack that they are created in, so that they can access any of these stack variables. This is a closure.
It is clear that you could have lambdas without closures, by either disallowing accessing any non-globals in your lambdas, or just having the behavior be undefined if the function accesses any variables that have left scope. In practice this makes for lots and lots of bugs, so the solution is closures.
The C++ way of combining a function with state, is to use a class (or a struct). Here's the C++ way of doing the above:
class accum {
int x;
accum(int x) : x(x) {}
int operator()(int i) {return x+=i}
}
Notice how you need to be explicit about what state you keep in the class. With closures the state kept around is implicit, but it is kept around too.
Lambdas and closures get mentioned together because they don't make sense apart. "Lambda" is just a fancy term for an anonymous function, but it also implies that the function is created (sans optimizations) dynamically (i.e. at runtime). This doesn't ever happen in C++, so hence the confusion.
A closure is the concept that a dynamically created function carries with it the state in which it was created (in C++ terms, the callstack). Imagine for a moment we had a C++ keyword called "lambda" that could create functions at runtime. What would the following code do?
You see the problem? "x" is no longer on the stack once foo() returns, but the function we return from foo accesses it! In fact doing anything meaningful with "x" is bogus. The solution is to have dynamically created functions like this to logically copy the call-stack that they are created in, so that they can access any of these stack variables. This is a closure.It is clear that you could have lambdas without closures, by either disallowing accessing any non-globals in your lambdas, or just having the behavior be undefined if the function accesses any variables that have left scope. In practice this makes for lots and lots of bugs, so the solution is closures.
The C++ way of combining a function with state, is to use a class (or a struct). Here's the C++ way of doing the above:
Notice how you need to be explicit about what state you keep in the class. With closures the state kept around is implicit, but it is kept around too.