Hi,
first of all, I think there is some confusion on what should be called closure and what should be called lambda function. I believe that the correct approach is to call the syntactic element in the language (e.g. (a, b) => a + b
in C#) lambda function. The created value is function value or a delegate in C#.
As implemented in .NET (both F# & C#), the delegate is actually a reference to some method in some class. The reason is that the delegate constructed using a lambda function syntax may need to keep some state:
Func<int, int> CreateAdder(int num) {
return arg => arg + num;
}
The returned delegate references some (unnamed) object, which stores the num
value and also the body of the lambda function. So, what is a closure? Closure is the object, which keeps the state needed to run the function value (or delgate). In this case, it is the unnamed object, which is referenced from the delegate and keeps the value of num
.
You also mentioned free and bound variables. If you look at the lambda function in the example above, it works with two variables. The variable arg
is declared as part of the lambda function. This would be called bound variable (in the lambda function), because it is declared as part of the lambda function. The num
variable would be called a free variable in the lambda function, because it is only used (but not declared!) in the scope of the lambda function. It comes from the outer scope (in this case, the method declaration).
The closure needs to capture all free variables in the lambda function. This means that all variables that are used inside the body, but are declared somewhere else are captured. However, the C# compiler doesn't just copy the current value. It turns it into a mutable field, so that it can be accessed (and also mutated) from all functions that may access it (and this is also the place where it becomes tricky). This would be a topic for a long blog post, but here is a brief example that you can use to experiment with this (using Tuple
from .NET 4.0, if you're using VS 2008, you can get C# implementation here in Chapter03/FunctionalCSharp):
Tuple<Func<int>, Action<int>> CreateReaderAndWriter(int initial) {
int state = initial;
return Tuple.Create( (() => state),
(newState => { state = newState; }) );
}
When you'll call this method, you'll get two functions as a result. The first one allows you to read the current state and the second one allows you to modify it. Note that the state is shared (because it is the same mutable variable)!
There has been a proposal by Don Syme from MSR to add support for closures directly to .NET. It is a bit academic, but it may help clarifying things a bit.