I recently posted twice (one and two) on anonymous delegates. I guess they really caught my attention for some reason, even though I've known about them for a long time. The remaining question to close out this debate is whether anonymous delegates are the .Net Framework answer to closures. Another related topic is continuations. I'm certain that these are not that.
First, what is a closure?
Here is how wikipedia defines closures: "Unlike garden-variety functions which retain no memory of what happened in previous calls, closures are capable of storing information across function calls."
Here is another explanation from guile, which is an open source scheme interpreter that I've never heard of before: "The concept of closure is the idea that a lambda expression "captures" the variable bindings that are in lexical scope at the point where the lambda expression occurs. The procedure created by the lambda expression can refer to and mutate the captured bindings, and the values of those bindings persist between procedure calls. "
My definition is (as of 5 mins ago): a closure is the outcome of capturing both the in-scope variables used by a block of code and the block of code itself to the end of preserving their relationship beyond the normal lifetime of those in-scope local variables. As a result, the local variables can be shared across all calls to the block of code (i.e. method).
So, do anonymous delegates in C# v2.0 conform to the definition of lexical closures? That seems to be a matter of great debate. It is amazing when you start to look at a topic and then you realize that there has been a whole crowd to the party before you. Anonymous delegates in C# appear to be just such a topic. Brad appears to have been interested in the topic about a year ago. Brad takes the stance (at least at that time) that anonymous delegates are not closures. abhinaba also takes the same stance. Dan Muller takes the opposite opinion, believing that C# has implemented closures.
I've come to the conclusion that anonymous delegates are closures. If you look at my somewhat-in-depth explanation of anonymous delegates in my last post, you'll see that the way they work seems to conform to the three definitions above. In summary, the C# compiler generates a class on your behalf which contains both an instance method (which is your anonymous delegate) and fields that map directly to the in-scope variables that you access in the containing method. All access to these variables are wired up to these generated fields on the class. That generated class is in itself the closure. Being heap-allocated, it naturally can have a different lifetime than what the containing method has on the stack, given that stack-frames have a tendency to go way.
I have a mail out to the C# team asking them their opinion on this interesting subject. I'm curious to see how they'll respond.