Just a quick post, haven’t shared anything in a while, but found this discussion on loop variables and closures interesting — well, inflammatory, actually.
Erik Lippert writes (and again) on C# loop variable closure semantics. The confusion arises because a “foreach” loop’s iteration variable is not assignable in C# — which leads the programmer to think it is constant — but actually it is variable, getting re-bound each iteration to the next item in the sequence. This normally wouldn’t matter much, but if you have a lambda that closes over that loop variable, the lambda will observe the re-bindings each iteration.
While searching for Haskell blogs, found this interesting response by one Adam Turoff. He mentions Ruby, JavaScript, and Scheme, but especially Haskell. He points out quite rightly that, in pure functional code, capturing a reference or copy is indistinguishable due to referential equality. C# was very close to getting this right — it prevents the user from rebinding the variable, but the real error was forgetting to prevent itself from doing the same.
However, the compiler isn’t really implementing a loop variable, it’s actually thin syntax over the .Current property of the iterator. The ‘foreach’ loop aims only to expose the CLR iterator pattern, so it makes sense that it would remain as close to it as possible. Another possible explanation: the real error was allowing the programmer to close over a variable that wasn’t really a variable.