4 ms·
C# made that change in C# 5 (2012) (https://ericlippert.com/2009/11/12/closing-over-the-loop-variable-considered-harmful-part-one/ https://ericlippert.com/2009/
by Someone 4y ago
C# made that change in C# 5 (2012) (https://ericlippert.com/2009/11/12/closing-over-the-loop-variable-considered-harmful-part-one/ https://ericlippert.com/2009/11/12/closing-over-the-loop-var...)
Swift had the problem in C-style for loops but not in “for…in” loops (https://www.timekl.com/blog/2015/11/26/variable-capture-in-go-vs-swift/ https://www.timekl.com/blog/2015/11/26/variable-capture-in-g...), but got rid of it when it removed C-style for loops altogether in Swift 3 (September 2016) (https://github.com/apple/swift-evolution/blob/main/proposals/0007-remove-c-style-for-loops.md https://github.com/apple/swift-evolution/blob/main/proposals...)
- saurik 4y agoI was shocked that C# would make this change--which is specifically to modify the scoping semantics of a C-style for loop to match those of a for-in loop, not to merely change the semantic of for-in loops; the latter seems entirely reasonable... while the former is just ridiculous to me (and OMG I am so glad I don't code in Go ;P)--but, the reference you cited for that in fact states the exact opposite: that they would never do such a strange thing (and, thereby, agrees with the person on reddit who made this post and who is adamantly against this change). > We have this same problem in for blocks, but for blocks are much looser about what “the loop variable” is; there can be more than one[1. or none at all.] variable declared in the for loop header, it can be incremented in odd ways, and it seems implausible that people would consider each iteration of the for loop to contain a fresh crop of variables. When you say for(int i; i < 10; i += 1) { ... } it seems dead obvious that the i += 1 means “increment the loop variable” and that there is one loop variable for the whole loop, not a new fresh variable i every time through! > We certainly would not make this proposed change apply to for loops.
- electroly 4y agoOP misunderstood but you have it right. C# did not change the behavior of "for" loops; they only changed "foreach" loops. As an example: List<Action> list = new(); for (var i = 0; i < 10; i++) list.Add(() => Console.WriteLine(i)); foreach (var action in list) action(); This (still) prints all 10s. All of the closures are referencing the same "i".
- tapirl 4y agoI don't misunderstand it. I know the facts in C#. But the Go proposal is different. The proposed change is for both "for;;" loops and "for-range" loops.
- electroly 4y agoI was referring to the HN poster "Someone" at the beginning of this subthread, my apologies for the confusion--I didn't want to name them explicitly in my post since that feels a little aggressive. They said C# 5 made this change, which is wrong; that's why I explained with a C# snippet. This subthread isn't referring to your post at all.
- tapirl 4y agoPlease note that, the Go proposal is for both "for-range" loops and traditional "for;;" c-like loops. I think it is okay to make the change for "for-range" loops, but not okay for traditional "for;;" c-like loops.