Could someone explain? I understand the basic concepts behind them but I often see them used interchangeably and I get confused.
And now that we're here, how do they differ from a regular function?
Could someone explain? I understand the basic concepts behind them but I often see them used interchangeably and I get confused.
And now that we're here, how do they differ from a regular function?
A lambda is just an anonymous function - a function defined with no name. In some languages, such as Scheme, they are equivalent to named functions. In fact, the function definition is re-written as binding a lambda to a variable internally. In other languages, like Python, there are some (rather needless) distinctions between them, but they behave the same way otherwise.
A closure is any function which closes over the environment in which it was defined. This means that it can access variables not in its parameter list. Examples:
def func(): return h
def anotherfunc(h):
return func()
This will cause an error, because func
does not close over the environment in anotherfunc
- h
is undefined. func
only closes over the global environment. This will work:
def anotherfunc(h):
def func(): return h
return func()
Because here, func
is defined in anotherfunc
, and in python 2.3 and greater (or some number like this) when they almost got closures correct (mutation still doesn't work), this means that it closes over anotherfunc
's environment and can access variables inside of it. In Python 3.1+, mutation works too when using the nonlocal
keyword.
Another important point - func
will continue to close over anotherfunc
's environment even when it's no longer being evaluated in anotherfunc
. This code will also work:
def anotherfunc(h):
def func(): return h
return func
print anotherfunc(10)()
This will print 10.
This, as you notice, has nothing to do with lambdas - they are two different (although related) concepts.
There is a lot of confusion around lambdas and closures, even in the answers to this StackOverflow question here. Instead of asking random programmers who learned about closures from practice with certain programming languages or other clueless programmers, take a journey to the source (where it all began). And since lambdas and closures come from Lambda Calculus invented by Alonzo Church back in the '30s before first electronic computers even existed, this is the source I'm talking about.
Lambda Calculus is the simplest programming language in the world. The only things you can do in it:►
f x
.f
is the function and x
is its only parameter)λ
(lambda), then the symbolic name (e.g. x
), then a dot .
before the expression. This then converts the expression into a function expecting one parameter.λx.x+2
takes the expression x+2
and tells that the symbol x
in this expression is a bound variable – it can be substituted with a value you supply as a parameter.(λx.x+2) 7
. Then the expression (in this case a literal value) 7
is substituted as x
in the subexpression x+2
of the applied lambda, so you get 7+2
, which then reduces to 9
by common arithmetics rules.So we've solved one of the mysteries:
lambda is the anonymous function from the example above, λx.x+2
.
function(x) { return x+2; }
and you can immediately apply it to some parameter like this:
(function(x) { return x+2; })(7)
or you can store this anonymous function (lambda) into some variable:
var f = function(x) { return x+2; }
which effectively gives it a name f
, allowing you to refer to it and call it multiple times later, e.g.:
alert( f(7) + f(10) ); // should print 21 in the message box
But you didn't have to name it. You could call it immediately:
alert( function(x) { return x+2; } (7) ); // should print 9 in the message box
In LISP, lambdas are made like this:
(lambda (x) (+ x 2))
and you can call such a lambda by applying it immediately to a parameter:
( (lambda (x) (+ x 2)) 7 )
As I said, what the lambda abstraction does is binding a symbol in its subexpression, so that it becomes a substitutible parameter. Such a symbol is called bound. But what if there are other symbols in the expression? For example: λx.x/y+2
. In this expression, the symbol x
is bound by the lambda abstraction λx.
preceding it. But the other symbol, y
, is not bound – it is free. We don't know what it is and where it comes from, so we don't know what it means and what value it represents, and therefore we cannot evaluate that expression until we figure out what y
means.
In fact, the same goes with the other two symbols, 2
and +
. It's just that we are so familiar with these two symbols that we usually forget that the computer doesn't know them and we need to tell it what they mean by defining them somewhere, e.g. in a library or the language itself.
You can think of the free symbols as defined somewhere else, outside the expression, in its "surrounding context", which is called its environment. The environment might be a bigger expression that this expression is a part of (as Qui-Gon Jinn said: "There's always a bigger fish" ;) ), or in some library, or in the language itself (as a primitive).
This lets us divide lambda expressions into two categories:
You can CLOSE an open lambda expression by supplying the environment, which defines all these free symbols by binding them to some values (which may be numbers, strings, anonymous functions aka lambdas, whatever…).
And here comes the closure part:
The closure of a lambda expression is this particular set of symbols defined in the outer context (environment) that give values to the free symbols in this expression, making them non-free anymore. It turns an open lambda expression, which still contains some "undefined" free symbols, into a closed one, which doesn't have any free symbols anymore.
For example, if you have the following lambda expression: λx.x/y+2
, the symbol x
is bound, while the symbol y
is free, therefore the expression is open
and cannot be evaluated unless you say what y
means (and the same with +
and 2
, which are also free). But suppose that you also have an environment like this:
{ y: 3,
+: [built-in addition],
2: [built-in number],
q: 42,
w: 5 }
This environment supplies definitions for all the "undefined" (free) symbols from our lambda expression (y
, +
, 2
), and several extra symbols (q
, w
). The symbols that we need to be defined are this subset of the environment:
{ y: 3,
+: [built-in addition],
2: [built-in number] }
and this is precisely the closure of our lambda expression :>
In other words, it closes an open lambda expression. This is where the name closure came from in the first place, and this is why so many people's answers in this thread are not quite correct :P
Well, the corporate marketoids of Sun/Oracle, Microsoft, Google etc. are to blame, because that's what they called these constructs in their languages (Java, C#, Go etc.). They often call "closures" what are supposed to be just lambdas. Or they call "closures" a particular technique they used to implement lexical scoping, that is, the fact that a function can access the variables that were defined in its outer scope at the time of its definition. They often say that the function "encloses" these variables, that is, captures them into some data structure to save them from being destroyed after the outer function finishes executing. But this is just made-up post factum "folklore etymology" and marketing, which only makes things more confusing, because every language vendor uses its own terminology.
And it's even worse because of the fact that there's always a bit of truth in what they say, which does not allow you to easily dismiss it as false :P Let me explain:
If you want to implement a language that uses lambdas as first-class citizens, you need to allow them to use symbols defined in their surrounding context (that is, to use free variables in your lambdas). And these symbols must be there even when the surrounding function returns. The problem is that these symbols are bound to some local storage of the function (usually on the call stack), which won't be there anymore when the function returns. Therefore, in order for a lambda to work the way you expect, you need to somehow "capture" all these free variables from its outer context and save them for later, even when the outer context will be gone. That is, you need to find the closure of your lambda (all these external variables it uses) and store it somewhere else (either by making a copy, or by preparing space for them upfront, somewhere else than on the stack). The actual method you use to achieve this goal is an "implementation detail" of your language. What's important here is the closure, which is the set of free variables from the environment of your lambda that need to be saved somewhere.
It didn't took too long for people to start calling the actual data structure they use in their language's implementations to implement closure as the "closure" itself. The structure usually looks something like this:
Closure {
[pointer to the lambda function's machine code],
[pointer to the lambda function's environment]
}
and these data structures are being passed around as parameters to other functions, returned from functions, and stored in variables, to represent lambdas, and allowing them to access their enclosing environment as well as the machine code to run in that context. But it's just a way (one of many) to implement closure, not the closure itself.
As I explained above, the closure of a lambda expression is the subset of definitions in its environment that give values to the free variables contained in that lambda expression, effectively closing the expression (turning an open lambda expression, which cannot be evaluated yet, into a closed lambda expression, which can then be evaluated, since all the symbols contained in it are now defined).
Anything else is just a "cargo cult" and "voo-doo magic" of programmers and language vendors unaware of the real roots of these notions.
I hope that answers your questions. But if you had any follow-up questions, feel free to ask them in the comments, and I'll try to explain it better.
When most people think of functions, they think of named functions:
function foo() { return "This string is returned from the 'foo' function"; }
These are called by name, of course:
foo(); //returns the string above
With lambda expressions, you can have anonymous functions:
@foo = lambda() {return "This is returned from a function without a name";}
With the above example, you can call the lambda through the variable it was assigned to:
foo();
More useful than assigning anonymous functions to variables, however, are passing them to or from higher-order functions, i.e., functions that accept/return other functions. In a lot of these cases, naming a function is unecessary:
function filter(list, predicate)
{ @filteredList = [];
for-each (@x in list) if (predicate(x)) filteredList.add(x);
return filteredList;
}
//filter for even numbers
filter([0,1,2,3,4,5,6], lambda(x) {return (x mod 2 == 0)});
A closure may be a named or anonymous function, but is known as such when it "closes over" variables in the scope where the function is defined, i.e., the closure will still refer to the environment with any outer variables that are used in the closure itself. Here's a named closure:
@x = 0;
function incrementX() { x = x + 1;}
incrementX(); // x now equals 1
That doesn't seem like much but what if this was all in another function and you passed incrementX
to an external function?
function foo()
{ @x = 0;
function incrementX()
{ x = x + 1;
return x;
}
return incrementX;
}
@y = foo(); // y = closure of incrementX over foo.x
y(); //returns 1 (y.x == 0 + 1)
y(); //returns 2 (y.x == 1 + 1)
This is how you get stateful objects in functional programming. Since naming "incrementX" isn't needed, you can use a lambda in this case:
function foo()
{ @x = 0;
return lambda()
{ x = x + 1;
return x;
};
}
Not all closures are lambdas and not all lambdas are closures. Both are functions, but not necessarily in the manner we're used to knowing.
A lambda is essentially a function that is defined inline rather than the standard method of declaring functions. Lambdas can frequently be passed around as objects.
A closure is a function that encloses its surrounding state by referencing fields external to its body. The enclosed state remains across invocations of the closure.
In an object-oriented language, closures are normally provided through objects. However, some OO languages (e.g. C#) implement special functionality that is closer to the definition of closures provided by purely functional languages (such as lisp) that do not have objects to enclose state.
What's interesting is that the introduction of Lambdas and Closures in C# brings functional programming closer to mainstream usage.
It's as simple as this: lambda is a language construct, i.e. simply syntax for anonymous functions; a closure is a technique to implement it -- or any first-class functions, for that matter, named or anonymous.
More precisely, a closure is how a first-class function is represented at runtime, as a pair of its "code" and an environment "closing" over all the non-local variables used in that code. This way, those variables are still accessible even when the outer scopes where they originate have already been exited.
Unfortunately, there are many languages out there that do not support functions as first-class values, or only support them in crippled form. So people often use the term "closure" to distinguish "the real thing".
From the view of programming languages, they are completely two different things.
Basically for a Turing complete language we only needs very limited elements, e.g. abstraction, application and reduction. Abstraction and application provides the way you can build up lamdba expression, and reduction dertermines the meaning of the lambda expression.
Lambda provides a way you can abstract the computation process out. for example, to compute the sum of two numbers, a process which takes two parameters x, y and returns x+y can be abstracted out. In scheme, you can write it as
(lambda (x y) (+ x y))
You can rename the parameters, but the task that it completes doesn't change. In almost all of programming languages, you can give the lambda expression a name, which are named functions. But there is no much difference, they can be conceptually considered as just syntax sugar.
OK, now imagine how this can be implemented. Whenever we apply the lambda expression to some expressions, e.g.
((lambda (x y) (+ x y)) 2 3)
We can simply substitute the parameters with the expression to be evaluated. This model is already very powerful. But this model doesn't enable us to change the values of symbols, e.g. We can't mimic the change of status. Thus we need a more complex model. To make it short, whenever we want to calculate the meaning of the lambda expression, we put the pair of symbol and the corresponding value into an environment(or table). Then the rest (+ x y) is evaluated by looking up the corresponding symbols in the table. Now if we provide some primitives to operate on the environment directly, we can model the changes of status!
With this background, check this function:
(lambda (x y) (+ x y z))
We know that when we evaluate the lambda expression, x y will be bound in a new table. But how and where can we look z up? Actually z is called a free variable. There must be an outer an environment which contains z. Otherwise the meaning of the expression can't be determined by only binding x and y. To make this clear, you can write something as follows in scheme:
((lambda (z) (lambda (x y) (+ x y z))) 1)
So z would be bound to 1 in an outer table. We still get a function which accepts two parameters but the real meaning of it also depends on the outer environment. In other words the outer environment closes on the free variables. With the help of set!, we can make the function stateful, i.e, it's not a function in the sense of maths. What it returns not only depends on the input, but z as well.
This is something you already know very well, a method of objects almost always relies on the state of objects. That's why some people say "closures are poor man's objects. " But we could also consider objects as poor man's closures since we really like first class functions.
I use scheme to illustrate the ideas due to that scheme is one of the earliest language which has real closures. All of the materials here are much better presented in SICP chapter 3.
To sum up, lambda and closure are really different concepts. A lambda is a function. A closure is a pair of lambda and the corresponding environment which closes the lambda.
Concept is same as described above, but if you are from PHP background, this further explain using PHP code.
$input = array(1, 2, 3, 4, 5);
$output = array_filter($input, function ($v) { return $v > 2; });
function ($v) { return $v > 2; } is the lambda function definition. We can even store it in a variable, so it can be reusable:
$max = function ($v) { return $v > 2; };
$input = array(1, 2, 3, 4, 5);
$output = array_filter($input, $max);
Now, what if you want to change the maximum number allowed in the filtered array? You would have to write another lambda function or create a closure (PHP 5.3):
$max_comp = function ($max) {
return function ($v) use ($max) { return $v > $max; };
};
$input = array(1, 2, 3, 4, 5);
$output = array_filter($input, $max_comp(2));
A closure is a function that is evaluated in its own environment, which has one or more bound variables that can be accessed when the function is called. They come from the functional programming world, where there are a number of concepts in play. Closures are like lambda functions, but smarter in the sense that they have the ability to interact with variables from the outside environment of where the closure is defined.
Here is a simpler example of PHP closure:
$string = "Hello World!";
$closure = function() use ($string) { echo $string; };
$closure();
This question is old and got many answers.
Now with Java 8 and Official Lambda that are unofficial closure projects, it revives the question.
The answer in Java context (via Lambdas and closures — what’s the difference?):
"A closure is a lambda expression paired with an environment that binds each of its free variables to a value. In Java, lambda expressions will be implemented by means of closures, so the two terms have come to be used interchangeably in the community."
A Lambda expression is just an anonymous function. in plain java, for example, you can write it like this:
Function<Person, Job> mapPersonToJob = new Function<Person, Job>() {
public Job apply(Person person) {
Job job = new Job(person.getPersonId(), person.getJobDescription());
return job;
}
};
where the class Function is just built in java code. Now you can call mapPersonToJob.apply(person)
somewhere to use it. thats just one example. Thats a lambda before there was syntax for it. Lambdas a short cut for this.
Closure:
a Lambda becomes a closure when it can access the variables outside of this scope. i guess you can say its magic, it magically can wrap around the environment it was created in and use the variables outside of its scope(outer scope. so to be clear, a closure means a lambda can access its OUTER SCOPE.
in Kotlin, a lambda can always access its closure (the variables that are in its outer scope)
Lambda vs Closure
Lambda
is anonymous function(method)
Closure
is function which closes over(capture) variables from its enclosing scope(e.g. non-local variables)
Java
interface Runnable {
void run();
}
class MyClass {
void foo(Runnable r) {
}
//Lambda
void lambdaExample() {
foo(() -> {});
}
//Closure
String s = "hello";
void closureExample() {
foo(() -> { s = "world";});
}
}
Swift[Closure]
class MyClass {
func foo(r:() -> Void) {}
func lambdaExample() {
foo(r: {})
}
var s = "hello"
func closureExample() {
foo(r: {s = "world"})
}
}
It depends on whether a function uses external variable or not to perform operation.
External variables - variables defined outside the scope of a function.
Lambda expressions are stateless because It depends on parameters, internal variables or constants to perform operations.
Function<Integer,Integer> lambda = t -> {
int n = 2
return t * n
}
Closures hold state because it uses external variables (i.e. variable defined outside the scope of the function body) along with parameters and constants to perform operations.
int n = 2
Function<Integer,Integer> closure = t -> {
return t * n
}
When Java creates closure, it keeps the variable n with the function so it can be referenced when passed to other functions or used anywhere.
Lambda is an anonymous function definition that is not (necessarily) bound to an identifier.
"Anonymous functions originate in the work of Alonzo Church in his invention of the lambda calculus, in which all functions are anonymous" - Wikipedia
Closure is the lambda function implementation.
"Peter J. Landin defined the term closure in 1964 as having an environment part and a control part as used by his SECD machine for evaluating expressions" - Wikipedia
The generic explanation of Lambda and Closure is covered in the other responses.
For those from a C++ background, Lambda expressions were introduced in C++11. Think of Lambdas as a convenient way to create anonymous functions and function objects.
"The distinction between a lambda and the corresponding closure is precisely equivalent to the distinction between a class and an instance of the class. A class exists only in source code; it doesn’t exist at runtime. What exists at runtime are objects of the class type. Closures are to lambdas as objects are to classes. This should not be a surprise, because each lambda expression causes a unique class to be generated (during compilation) and also causes an object of that class type, a closure to be created (at runtime)." - Scott Myers
C++ allows us to examine the nuances of Lambda and Closure as you have to explicitly specify the free variables to be captured.
In the sample below, the Lambda expression has no free variables, an empty capture list ([]
). It’s essentially an ordinary function and no closure is required in the strictest sense. So it can even be passed as a function pointer argument.
void register_func(void(*f)(int val)) // Works only with an EMPTY capture list
{
int val = 3;
f(val);
}
int main()
{
int env = 5;
register_func( [](int val){ /* lambda body can access only val variable*/ } );
}
As soon as a free variable from the surrounding environment is introduced in the capture list ([env]
), a Closure has to be generated.
register_func( [env](int val){ /* lambda body can access val and env variables*/ } );
Since this is no longer an ordinary function, but a closure instead, it produces a compilation error.no suitable conversion function from "lambda []void (int val)->void" to "void (*)(int val)" exists
The error can be fixed with a function wrapper std::function
which accepts any callable target including a generated closure.
void register_func(std::function<void(int val)> f)
See Lambda and Closure for a detailed explanation with a C++ example.