Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I've mentioned this elsewhere but I think the following needs to be emphasised: "The "for" loop will not be changed."[1]

I would argue it's a terrible idea to break consistency between how this is handled by the for and the foreach loop. The for loop can't be changed because the initialiser expression is general and not restricted to variables. I expect the result will be many bemused developers surprised closures behave one way in a for and another way in a foreach.

The end result is that the problem hasn't really been eliminated, just made even more obscure. My personal preference would be for consistency; one can still achieve the desired effect simply by explicitly defining a variable inside the loop scope for the closure to close over.

[1] http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closi...



Closures behave the same way in either case. The closure semantics in C#5 will be unchanged.

The difference is that the for loop's variable is scoped to the entire loop, whereas the foreach loop's variable is only scoped to the embedded statement (i.e., an iteration through the loop). That difference is perfectly justifiable.

In the semantics of a for loop, the loop variable is very clearly (and necessarily) a persistent value which can be changed according to rules described in the loop statement, by code within its embedded statement, or both.

In the semantics of a foreach loop, on the other hand, the implication is that you're successively retrieving otherwise independent values from a collection and operating on each one in succession. There is no reason to need or expect that the variable will have a scope that extends outside the embedded statement. It is simply replaced on each iteration through the loop. The loop statement doesn't offer any opportunity to perform any logic on the variable in between iterations, since all you can do between the parentheses is bind a variable. You cannot use a varaible from the outer scope as the loop variable, and the loop variable goes out of scope as soon as the loop exits.

In fact, there is really only one place where this scoping difference is visible: When the loop contains a closure. In that case, the semantics that C#5 will use are indisputably superior. Even in cases where that sort of behavior is desired (which is exceedingly rare), it is much better to require that the behavior be accomplished by using a variable from the outer scope, for the sake of readability. Being a language in which it is easy to write obfuscated code was never high in C#'s priority list.

If the cost of doing it this way is that there is a(nother) difference between the semantics of the for-loop and the foreach-loop, I have no problem with that. I can see no demonstrable need for consistency there; it is a foolish consistency.


I never implied closure behaviour would change, only the variable scoping is inconsistent. I agree it makes sense, but it's still going to cause surprises.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: