views:

651

answers:

6

Why do closures exist for anonymous methods? Why not just pass state into the method without the overhead of a new class being generated with the closure variables being copied in? Isn't this just a throwback to "making everything global?"

Someone talk me down, I feel like i'm missing something here...

+3  A: 

The overhead of creating a new class probably isn't something to worry about. It's just a convenient way for the CLR to make bound variables (those captured by the closure) available on the heap. They are still only accessible within the scope of the closure, so they're at all not "global" in the traditional sense.

I believe the reason for their existence is mainly convenience for the programmer. In fact, it's purely that as far as I'm concerned. You could emulate the behaviour of a closure pretty well before they existed in C#, but you don't get any of the simplicity and syntactical sugar that C# 3.0 offers. The entire point about closures is that you don't need to pass the variables in the parent scope to the function, because they're automatically bound. It's much easier and cleaner for the programer to work with, really, if you consider that the alternative is true global variables.

Noldorin
A: 

Because the CLR takes care of it, the easiest way to "pass state into the method" is to auto-generate a class, which encapsulates that state.

eulerfx
The CLR has nothing to do with it - it is the compiler...
Marc Gravell
I meant the CLR takes care of it in the sense that when the compiler generates the class, the fact that its a class takes care of those variables being passed on, I guess I was unclear.
eulerfx
A: 

At least one thought is that closures exist in other languages such as javascript. So they probably included closures to be in line with people's prior experience with anonymous methods.

Joel Martinez
+7  A: 

Purely, convenience... you don't know how much state you are going to need when defining, for example, a Predicate<T> - consider:

List<int> data = new List<int> {1,2,3,4,5,6,7,8,9,10};
int min = int.Parse(Console.ReadLine()), max = int.Parse(Console.ReadLine());
List<int> filtered = data.FindAll(i => i >= min && i <= max);

here we've passed two additional bits of state into Predicate<T> (min and max) - but we can't define List<T>.FindAll(Predicate<T>) to know about that, as that is a caller detail.

The alternative is to write the classes ourselves, but that is hard, even if we are lazy:

class Finder {
    public int min, max;
    public bool CheckItem(int i) { return i >= min && i <= max;}
}
...
Finder finder = new Finder();
finder.min = int.Parse(Console.ReadLine());
finder.max = int.Parse(Console.ReadLine());
List<int> filtered = data.FindAll(finder.CheckItem);

I don't know about you, but I prefer the version with the closure... especially when you consider how complex it gets when you have multiple contextual levels. I want the compiler to worry about it.

Consider also how often you use such constructs, especially for things like LINQ: you wouldn't want to have to do it any other way...

Marc Gravell
Excellent, and well argued; thank you!
Jason Watts
A: 

Because you take write this:

var divsor = [...]
for(int x = 0; x < 10000000; x++){
     source[x] = source[x] / divsor         
}

And easily turn it into this

var divsor = [...]
Parallel.For(int x = 0; x < 10000000; x++, ()=> {
     source[x] = source[x] / divsor         
})
Jonathan Allen
A: 

Some methods require a specific signature. For example:

public void set_name_on_click(string name)
{
    button.Click += (s,e) => { button.Text = name; };
}

A full closure solves this very neatly. You really don't want to mess with the anonymous methods signature.

Ray