First lets see how the sample works in a language like Ruby which implements true lexical closure.

$arr = Array.new

# function funcGen fills the array arr with generated

# functions (closures) that print an integer i. i varies

# from 0 to val (10) when the function is generated

def

funcGen(val)

0.upto(val)

do |i| # same as for(i=0;i<val;i++)

$arr[i] = Proc.new {

# Proc.new creates the closure

print i

# body of the closure

print

' '

}

end

end

funcGen(10)

# call funcGen to fill the array# each function in the array arr is called to print

# the value of i

$arr.each

do |val|

val.call

end

Definition of closure requires that the lexical state of the closure when it's created is preserved. So all the variables (environment) used by the closure at the timeof its creation should be captured at a point in time. Since Ruby implementes true closure and it does this the result of running the above code is

0 1 2 3 4 5 6 7 8 9 10

If we see the same sample in C# it'll be some thing like

using

System;

namespace

AnonymousMethod

{

delegatevoid Func();

class Program

{

static Func[] funcArr = new Func[10];

staticvoid fillFunc(int count)

{

for (int i = 0; i < count; i++)

{

funcArr[i] =

delegate()

{

Console.Write("{0} ", i);

};

}

}

staticvoid Main(string[] args)

{

fillFunc(funcArr.Length);

for (int i = 0; i < funcArr.Length; i++)

{

funcArr[i]();

}

}

}

}

However, even though the same logic as in Ruby is implemented in this C# code the result is totally different and is

10 10 10 10 10 10 10 10 10 10

So in this case the value of i when the anonymous method was created is NOT used and the last modified value of i is used. This clearly indicates that lexical environment of all these methods are not closed. In anonymous methods these read-only variables are shared between the outer method and all the other anonymous mehtods. This sample can be tweaked a little to get it to match that of Ruby. The modified sample is as below with all changes marked in bold

using

System;

namespace

AnonymousMethod

{

delegatevoid Func();

class Program

{

static Func[] funcArr = new Func[10];

staticvoid fillFunc(int count)

{

for (int i = 0; i < count; i++)

{

int j = i;

funcArr[i] =

delegate()

{

Console.Write("{0} ", j);

};

}

}

staticvoid Main(string[] args)

{

fillFunc(funcArr.Length);

for (int i = 0; i < funcArr.Length; i++)

{

funcArr[i]();

}

}

}

}

With this change in code the output will get changed and will be the same as the Ruby program (0 1 2 3 4 5 6 7 8 9). The difference in the result further strengthens the fact that true closure is not implemented by C#. Inspection of the generated assembly with Reflector clearly shows why...

In either case to encapsulate the anoymous method and the variable i it referes to the compiler generates a class

[CompilerGenerated]

privatesealedclass <>c__DisplayClass2

{

public <>c__DisplayClass2();

publicvoid <fillFunc>b__0()

{

Console.Write(

"{0} ", this.i);

}

publicint i;

}

The method in bold is the anonymous method.

In the first case while parsing the fillFunc method the compiler sees the following code

for (int i = 0; i < count; i++)

{

funcArr[i] = delegate()

{

Console.Write("{0} ", i);

};

}

and figures out that a variable i from the outer scope is used by the anonymous method and the compiler emits the following code

private

staticvoid fillFunc(int count)

{

Func func1 = null;

Program.<>c__DisplayClass2 class1 = newProgram.<>c__DisplayClass2();

class1.i = 0;

while (class1.i < count)

{

if (func1 == null)

{

func1 =

newFunc(class1.<fillFunc>b__0);

}

Program.funcArr[class1.i] = func1;

class1.i++;

}

}

It is obvious from this code that only one object class1 of the generated class is created and is shared between all the anonymous methods and the loop generating the methods. So if anyone of the methods are called later, the last modified value of i (= 10) will be returned.

For the second case on seeing

staticvoid fillFunc(int count)

{

for (int i = 0; i < count; i++)

{

int j = i;

funcArr[i] = delegate()

{

Console.Write("{0} ", j);

};

}

}

The compiler generates the following code

private

staticvoid fillFunc(int count)

{

for (int num1 = 0; num1 < count; num1++)

{

Program.<>c__DisplayClass1 class1 =

new Program.<>c__DisplayClass1();

class1.j = num1;

Program.funcArr[num1] =

new Func(class1.<fillFunc>b__0);

}

}

Here the class used to encapsulate the anonymous method is very similiar to the one used in the first case. However, since the method uses a variable inside the loop, for each iteration a new object is created. This results is each anonymous methods having its own copy of the object and hence the value of j in it is same as it was at the time of the method creation.

Actually, this demonstrates why C# does have true lexical closure. In the first C# example, i has a single lexical binding during definition of all the functions, and they all share that one binding, so they all print its current value.

Similar Common Lisp code (using a list instead of an array) looks like this:

In your second C# example, j is introduced as a name binding in the loop body; thus a different binding is seen by each created function. This is exactly as expected with lexical closure.

Ruby has odd rules with respect to the lexical binding of names. Since i is not defined before the loop, the i in the loop acts like a parameter to the loop body, which means that it is bound anew on each iteration. If you simply add the statement "i = 0" before the loop, i is now lexically bound outside the loop, and you get results similar to the C# case (except you’ll print tens instead of elevenses, due to the fencepost error in your examples).

To clarify Gabe, what I tried to show was that if C# did implement true closure then in either case the same result should have been obtained and tweaking to get the desired effect would have not been required.

Definitions of Lexical closures seem to vary and so does the opinion on whether C# implements closure. To quote Brad Adams (http://blogs.msdn.com/brada/archive/2004/08/03/207164.aspx) "Anonymous methods are not closures or completions. They are anonymous methods. They allow sharing of variables with the outer method (not copy in, or copy out, or copy in-out, or even by ref) "

In one definition of closure from the C2 wiki is that "In proper closures, not just the value is kept, but a reference to the actual object passed in". In this case C# does implement closure.

Again in another definition "during the creation of the closure the lexical environment is captured". In C# since changes made in child scope propagate to the parent scope and to all other closures it does not implement closure.

Yes, James, that’s the expected output. Sorry that I forgot to include it with my examples.

In the discussion of BradA’s referenced blog, Ian Griffiths asks the right question, and the answer is that the sharing of lexical variables, not just values, is expected of closures. This is the definition that Lisp has used since long before Ruby or C# existed.

The only sense in which anonymous methods could be considered different from closures is that they are methods rather than functions. But this is a fairly trivial difference. In essence, the implicit ‘this’ variable is just another lexical variable that is captured in the closure.

I interpreted the definition of lexical closure is to share values not variables. In case it is sharing of variables then C# does implement lexical closure. This brings up an interesting thought, why do people in the C# team including BradA and Eric always say that anonymous methods are not closures?

Anyways, all these discussions sooner or later lead to Lisp/Scheme/Ruby. I guess I have to start on Lisp soon…..

abhinaba: That’s indeed a good question. If I had to guess based on that other blog, I’d say BradA is relying on C2 and wikipedia for definitions. Not an unreasonable notion, but it happens to fail in this instance. I think the Common Lisp definition is arguably a better choice due to its age.

You might consider drawing their attention to this exchange to see what they have to say.

As I understand it, ML, being a pure functional language, has immutable ‘variables’. In such languages, the distinction between name/value and name/variable mappings is irrelevant. Thus the wikipedia entry’s choice of using ML as an example is unfortunate.

I definitely recommend learnign Lisp. I studied the pre-standardization document (Guy Steele’s "Common Lisp" ) in detail early in my career (just prior to standardization), and it helped me immensely in understanding many issues of programming language design.

Nowadays I doubt I’d have the fortitude to read through a language specification like this, though. Too busy reading blogs. 🙂

ML is not a pure functional language, it is an impure functional language (Haskell is an example of a pure functional language). So ML has both mutable and immutable variables.

The OCaml equivalent of the original example programs is simply:

let arr =

Array.init 11 (fun i () -> Printf.printf "%d " i)

Array.iter (fun f -> f ()) arr

The first line creates an array of closures, each of which prints its own index in the array. The second line applies the final argument "()" to each of the closures, invoking them in turn and printing out the consecutive integers 0..10.

I have no idea whether or not C# supports first-class lexical closures. I do know that other languages will have a tough time trying to beat the brevity and performance of ML though.

Cheers,

Jon.

PS: Don’t try to learn anything about functional programming from Wikipedia – the articles are mostly awful and they seem to be getting worse…

I believe that the point Ian Griffiths made on BradA’s blog about the definition of closure being too implementation specific is at the center of the confusion here.

In Lisp, the compiler actually creates "a closure", a container if you will, for the lexical context of the function. In .NET, according to the discussion on BradA’s blog and inferred from Eric Gunnerson’s comments on Channel9, the variables referenced by the anonymous methods are moved from the stack to the heap so that the "closed over" variables can be referenced in a shared manner independent of the lexical scope where they were declared.

In short, the difference between "a closure" and an "anonymous method" is semantics. They both form a logical lexical closure. They only vary in their implementations.

int i is local to the for loop block so it is always reinitialize; the scope of for loop blocks changed about 2000-2002 (can't remember). if you were to use a while loop and declare the int i outside the while loop then you would get the expected behavior. In the Ruby example, the for loop scoping is similar to the old school C for loop style scoping.