-
-
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
scoping issues, part 1 #423
Comments
A variable introduced in a scope is inherited by all inner scopes, unless one of the inner scopes overrides that. So in A variable can be "introduced" by either declaration or assignment. In Python, the problem was that there were certain reassigning operations that were not possible to achieve. We don't have that problem, since the default is to fully inherit variables. We did things this way so assignment can implicitly create variables in an unsurprising way, without the distinction between Would you suggest something like |
Assignment shouldn't introduce new variables. You should require |
I feel strongly that avoiding the verbosity of writing The main thing here is that you never have to scan beyond an obvious and usually quite limited, and always contiguous region of code to figure out where a variable is local to. Using functions as the typical example of a new scope at the top level, any variable assigned inside the function must be local unless it is explicitly declared to be global; anything that's never assigned must be global or a parameter (which is also obvious). In other words the behavior that is what you almost always want— that assignments are to new local variables — is the default, easiest thing to accomplish. |
From a pure programming perspective, you're probably right, but matlab/octave/etc. users expect to be able to simply write |
Also, in practice, I never find that the current scheme is confusing — it just does what I want. I agree, however, that reading the rules in the manual it sounds a little complicated. But that's often the way to get something that just works intuitively — the rules need to be a little complicated. |
If you don't like a keyword, how about using |
I gotta say, I'm pretty happy with how this works right now. Give it a chance to grow on you. If we get lots of people who hate the way this works, we should obviously reconsider, but otherwise we'll leave it as is. |
I tend to agree with @StefanKarpinski. I quite like the way it works now. It's straightforward, clean and simple, and it avoids dangerous unexpected behavior (like changing the value of a global inadvertently). |
Thank you for your explanation. I understand you want But some day a Julia user might learn that it's bad practice to use global variables. So she decides to change this code:
into this code:
The first prints
The first prints The current scoping rules get out of your way for a long time. Until they don't. This may happen once per week, once per year, but it will happen. To you. And it will be nasty. Julia gets a lot of things right, please make the scoping rules be one of them. |
You definitely have a point here. Of course we don't want to "fix" this by making the first case print 10. This might be acceptable, since I find it quite rare to modify one function's variables from an inner function.
in that case you would have to add "outer" declarations. Also a bit of a concern for macros, but there it could be solved by a hygiene system in the future. |
I agree that there's something wrong here. The smoking gun for me is not being able to move code from a local scope to a global scope and have it work the same. Another smell is how the repl needs to use trickery to emulate a local scope that's pseudo-global. The question is how to fix it without sacrificing the good parts of what we have now. |
Here's an idea for how to fix this. The idea is to have "hard scope" and "soft scope". Functions introduce "hard scope" whereas various blocks introduce "soft scope". The difference would that in a new hard scope, assignment without a "global" or (hypothetical) "outer" declaration always creates a new variable local to that scope, regardless of whether a variable with that name exists in the outer scope. In a new soft scope, assignment updates a variable in the outer scope if such a variable exists or creates a new inner-scoped variable if no such variable exists. Some examples of the proposed behavior (not how things work now):
Works: prints 0 through 9.
Fails: complains that |
That is actually a fix for issue #424, not this one. |
Yeah, that's true. I thought this conversation had converged with that one. |
Nevertheless, what do you think? |
The hard-scope, soft-scope distinction actually already existed, but the problem was that I sometimes expanded expressions in a file before prior expressions had been evaluated. I will do a commit soon that fixes this to make loading from a file identical to entering stuff in the repl. |
!!! |
This #423 (comment) is the main potential issue here but it seems like we're at an optimal behavior now. Ergo, closing. |
Stdlib: SparseArrays URL: https://github.com/JuliaSparse/SparseArrays.jl.git Stdlib branch: main Julia branch: master Old commit: 99c99b4 New commit: 54f4b39 Julia version: 1.11.0-DEV SparseArrays version: 1.11.0 Bump invoked by: @ViralBShah Powered by: [BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl) Diff: JuliaSparse/SparseArrays.jl@99c99b4...54f4b39 ``` $ git log --oneline 99c99b4..54f4b39 54f4b39 Fix docs conflict when building as part of full Julia docs (#430) a64ef4f Cleanup reloaded (#426) 4e2d1e4 Respect `IOContext` while displaying a `SparseMatrixCSC` (#423) 3d1eda9 Test suite: activate a temp project if we need to install Aqua.jl during the test suite (#425) 18b7fce Merge pull request #422 from JuliaSparse/jn/cat e2c78b8 test: restore ambiguous test 68afc6e fix inference of SparseVector cat c402d09 cat: ensure vararg is more inferrable 2c4f870 Fix some broken links (#421) 36a5308 bump version (#418) ``` Co-authored-by: Dilum Aluthge <dilum@aluthge.com>
Hello Julia developers,
congratulations with your great new language. I was singing 'O Julia' out loud all day yesterday.
But now my bug report. Notwithstanding the
let
,global
andlocal
keywords, it seems there is not always a clear distinction in Julia between variable declaration and assignment. This breaks encapsulation and can lead to hard to find bugs.Matlab's scoping rules we don't even need to discuss [1], Coffeescript is a disaster [2], please don't copy Ruby on this one [3], Perl and Javascript are ok as long as you don't forget your
my
's andvar
's (or use strict), Python fixed it in version 3 [4], and one could say Scheme got it right the first time in 1970 [5].What is the reasoning behind Julia's intricate scoping rules?
[1] http://www.mathworks.nl/help/techdoc/matlab_prog/f4-39683.html#f4-73993
[2] jashkenas/coffeescript#712
[3] http://www.rubyist.net/~matz/slides/rc2003/mgp00010.html
[4] http://www.python.org/dev/peps/pep-3104/
[5] http://news.ycombinator.com/item?id=3379962
The text was updated successfully, but these errors were encountered: