3 ms·
No, not really, it's a natural and unintended consequence of how the spec scopes variables in loops/switches/conditionals: https://golang.org/ref/spec#Blocks h
by Merovius 9y ago
No, not really, it's a natural and unintended consequence of how the spec scopes variables in loops/switches/conditionals:
https://golang.org/ref/spec#Blocks https://golang.org/ref/spec#Blocks
The problem you are trying to solve is, that with a statement like
for i := 0; i < n; i++ {
doAThing(i)
}
you want `i` to be valid inside the loop body, in the for-clauses but not outside the for-statement. Go solves this by saying that an if/for/switch statement has an implicit block surrounding them and that block is what scopes the loop variables. AFAIK no one considered, that this would have this consequence in relation to closures.
Performance wouldn't really matter, because compilers tend to be pretty good at optimizing these kinds of things. They already reorder when they check for the condition and how they jump non-intuitively and the naive instruction sequence would involve freeing some stack-space at the end of the loop, reallocating it in the next iteration and then writing the new value to it. Figuring out that you can save the actual stack-pointer operations isn't that hard.
- innagadadavida 9y agoCan the compiler implicitly copy i, basically convert it to: for i := 0; i < n; i++ { i := i doAThing(i) }
- Merovius 9y agoSure. It's an easy problem to fix, now that the team is aware it. I'm pretty sure they'll solve it for Go 2. In the meantime, it would break the compatibility promise, so it's just a kludge we have to live with. I basically just wanted to point out that the problem isn't so much an implementation question (or about performance). But that no one thought of it and it's now mainly a question of how to best phrase the spec for this :)