Back in 2002, I wrote the following about the proposal for an ‘enhanced for loop’ in Java 1.5.
Foreach takes probably the most common use of Smalltalk blocks, the internal iterator, and creates a syntactic special-case for them. Once again, it's a band-aid solution. Foreach removes the annoying duplicated syntax for the simplest case, but it does nothing to give programmers the chance to remove duplication on the more complex cases.
So it seems now for Java 7, closures having been dropped from the roadmap, it's time to apply the next band-aid. This time the recipient is the next in the line of usual suspects, resource management:
Absent a language change, you must close resources manually. That is why Java’s competitors have automatic resource management constructs (C# has using blocks and C++ has destructors).
Back to me from seven years ago:
Once foreach is implemented, the precedent has been set: whenever the lack of [closures] causes us to lag behind C#, don't fix the underlying problem, work around it with a variant on what we have already.
The funniest part, of course, is that C# 3.0 has had closures (or at least succinct lambda expressions with type inference) since 2007.
urghh, that resource management proposal is ugly, but the Disposable interface would be nice, particularly if retrofitted…
When you say " (or at least succinct lambda expressions with type inference)", what aspect of closures are you suggesting that C# is lacking?
I have no idea. I don't code in C# so I didn't want to make assumptions beyond what was written on the Wikipedia page.
Got to agree - it's getting a bit old.
We know you can do blocks & closures on the JVM - Groovy and JRuby (not to mention Scala) all show that. It can be implemented efficiently, with no loss of compatibility. The only reason we can't have blocks and closures in Java is that the various interested parties can't agree.
C# only has anonymous functions. In contrast to Ruby, Lisp and JavaScript they're not real closures because they don't close over lexical scope (that's why they're called "closures").
Without the computer science mumbo-jumbo that simply means you can't do this:
int x = 1;
execute(delegate() {
x = 2; // can't write to lexically scoped variable
});
Actually this code block in C# 3.0:
int x = 1; Console.WriteLine(x); Action foo = delegate() { x *= 2; }; foo(); Console.WriteLine(x); foo(); Console.WriteLine(x);Emits this:
That seems like a real closure to me because the execution of foo() affected the outer scope.
Oh that's neat! I was trying to work it out and found blog entries to the contrary but I suppose they were incorrect then.
Thanks for correcting me!
C# doesn't really support closures. In the above statement the delegate doesn't close around the variable, the delegate is just defined and used in the same scope as the variable is already in.
If the delegate were returned from the function, it would stop working because the variable would go out of scope - that is the delegate does not close around the variable, it is not a closure.
In most normal use this isn't really a problem however, and anyways real closures are comming with C#4.
Seems to me that closures are supported in C#. Parameter x is lexically captured in this code:
class Program { static void Main(string[] args) { var multiplier = CreateMultiplier(10); Console.WriteLine(multiplier(2)); Console.WriteLine(multiplier(3)); }static Func<int, int> CreateMultiplier(int x)
{
return y => x * y;
}
}
Thanks for the (mis)information, Anders. A couple of corrections.
C# really does support closures. In the above statement the delegate closes around the variable. The delegate is defined and used in the same scope as the variable's own scope, which is the very definition of closing over a variable.
If the delegate were returned from the function, it would continue working. That's because the variable remains in scope when the delegate is executing. The compiler arranges for this by allocating the variable on the heap rather than on the stack.
Lambda expressions, which are simply a more concise syntax for delegate expressions, were added in C# 3.0 and are already in widespread use.
-Neal Gafter (Java Closures author, C# language architect)