-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
always create new bindings for for
loop iteration variables
#22314
Comments
That'll be good for #14948 |
That issue is a bit different, since my proposal here will still allow writing to variables outside the loop. This would just make |
The only argument against this change that I can think of (putting aside backwards-compatibility issues) is that sometimes it is nice to be able to get the last iteration of a |
I wonder how many hours were spent debugging bugs because of this scoping rule. On the other hand, once one knows of this "feature", one usually exploits it in the way @stevengj described it. I am not sure if it is related, but when thinking of list comprehensions as shortcuts for julia> function f()
i = 1
[ i for i in 1:2]
println(i)
end
f (generic function with 1 method)
julia> f()
1 |
That behavior can also be useful for debugging at the REPL, when you want to know which iteration threw an error. Not saying we must necessarily keep it, though. I think the main goal should be language consistency to limit surprises and mistakes. |
Not the same, but #19324 proposed doing this (for all variables) at the top-level scope. Similarly, I think #8870 is related, since anything that makes a variable less likely to become (unnecessarily) global makes that code faster :P I know #14948 isn't directly related, but I think I've commented somewhere that this would make it valid to mark the for loop variable as |
The behavior I would expect is that the iterator variable in a
To address @nalimilan's use case, perhaps
I believe that currently, |
That's off the table; we decided quite a while ago that when loops introduce new variables they should be fresh on each iteration. Comprehensions also behave that way. One of the benefits of the change in this issue is that it makes for loops and other appearances of |
Understood. But I think the loop iterator is syntactically and conceptually different than variables introduced in the loop body.
|
Not going to happen. You can think of a loop either as an outer let-bound variable updated repeatedly inside, or as something more like a higher-order function that calls the body (a function of Nit pick: the variable doesn't determine how many times to repeat the body, the iterator does. The iterator does indeed exist outside the body; the variable needn't. |
Ok, parallelism is a good argument for having a fresh binding each iteration. Thanks for considering my viewpoint. |
We did originally do it the way you suggest, @benninkrs and changed it for a variety of reasons. The current per-iteration-local behavior tends to produce fewer surprising bugs and work better with higher order functions. As Jeff said, in for loops either behavior is justifiable, but in comprehensions, per-iteration is clearly less surprising – and having them match is overall better. I'm strongly in favor of this change – if you want the iteration variable to leak out of the for loop, it's much clearer coding style to explicitly assign it to another variable. If you write it that way, it's clear to anyone what's happening without needing to know the details of scoping rules, so forcing people to write it that way is a good thing. It significantly simplifies scoping behavior and removes a potentially surprising gotcha from the language. |
RFC: deprecate `for` loop vars that overwrite outer vars (#22314)
I thought there might be an issue for this already, but if so I can't find it.
We currently have this behavior:
In other words, if there is already an
i
in scope, thenfor i
will reuse it. Instead, thei
in the loop should probably be a new variable, equivalent to:The text was updated successfully, but these errors were encountered: