Thank you, I knew about the scoping, but not that you could use global in the loop!
But still this somehow feels broken, I cannot simply copy code out of a function in the REPL to debug it (In the lack of a proper debugger)
This really worries me. When we teach Julia, students typically start to code in global scope (in Jupyter) and at some point I tell them, āand if you now put everything in a function it might be even fasterā. However now, I have to tell them about scoping and āglobalā very early on, as they have to put 'globalās in the first place and remove them in the function, which I find suboptimal. Although I think I see the technical benefit, it feels to me that this is maybe trading too much of the userās convenience (I donāt know any interactive language where you would have to do something like this). After all Julia has not just been great for performance but also simple, naive usage. Just my two cents.
Iāll be an instructor for Engineering freshmen this fall and Iāll be teaching Julia. I have been thinking about this problem.
Since it is very āJulianā to write small functions I think the first thing Iām going to do is teach them how to write functions. Like tiny functions.
From that Iāll explain scoping rules, and how to refer to a variable defined outside the function.
Then I think of introducing for loops, if statements etc using small functions that need those.
Only after that Iād explain them that everything is a global in the REPL, so they have to be careful with this gotcha when tinkering on the REPL.
The point is they really should be writing small functions since the beginning.
Hi Guys, iām having the same problem in Jupyter Notebook. Iām creating my own Julia tutorial following the youtube āIntro to Juliaā video.
In a code cell I made it:
n=0
while n < 10
println(n)
n+=1
end
And the result was:
UndefVarError: n not defined
Stacktrace:
[1] top-level scope at ./In[18]:3 [inlined]
[2] top-level scope at ./none:0
Iāve tried to put the local status in any place but the result still goes wrong, the solution came following @saschatimme instructions (or at least how I interpreted that), like below:
It is not a bug.
It worked in Julia 0.6, in Julia 0.7 it gave a deprecation warning that you must add global, and in 1.0 it throws an error.
I really like favbaās idea of starting by introducing functions and teaching them to write tiny functions. Sounds like thatād also end up encouraging good coding habits.
This was a tough decision that we deliberated over for a very long time and had many conversations about. The old behavior was carefully designed to make the behavior of loops and other scope-introducing constructs the same in global scope or in the body of a function. However, the down side was that to accomplish this, whether an assignment inside of a loop or other non-function scope assigned to a global variable or created a new local variable depended on whether a global binding for that name already existed or notāwhich is not, in general, a statically predictable property. This also created a distinction between the kind of scope which a top-level loop or other non-function scope-introducing construct created and the kind which functions created. This behavior was widely misunderstood and often complained about when people were trying to wrap their heads around the scoping behavior.
Now, in 0.7/1.0 there is only one kind of scope: functions and loops and other scope constructs are all the same. So thatās much simpler and now whether a variable is local or global is always statically predictable. But the down side is that the same code in a function or on global scope do not behave the same anymore. This trade off is unavoidable given the way local variable are implicitly introduced in Juliaāwe really explored all the possible options for this. Languages that require you to declare local variables donāt have this problem but then again declaring the occasional global is a lot less difficult than declaring every local.
There is one possible way to recover the old ability to paste code from a function body into the REPL and have it behave the same, which is to automatically wrap the code in a let block to make the behavior like that in a function body. Weāll probably experiment with this in the future and see how well it works. It feels a bit weird to special case the REPL like this but it may be better.
Another question, the way I did is the right way? Cuz I tried to use ālocalā but didnāt work. Using global will not cause any trouble with other variables with same name in another loops or function?
Iām hosting a hands-on introduction to Julia for PhD-students in energy systems modeling. The whole mini-course will have three 2.5-hour sessions, and I just came back from the first session an hour ago. Four out of 12 students were stumped by this issue completely independently of each other. All four worked interactively in the REPL to make their code work before saving it to a file. None of these four had enough programming experience to know what scoping meant, but all are capable of hacking together Matlab scripts.
The bottom line is this. Programming newbies who try everything out in the global scope of the REPL find this scoping behavior completely counter-intuitive. This makes the language seem unfriendly, bordering on broken in this particular case.
As for me, I think scoping rules are an intermediate level topic and shouldnāt be necessary to bring up in an introductory-level course. If you just tell students to wrap all code in functions, even in the REPL, then suddenly the language seems quite a bit less interactive and harder to work with.
I understand why the scoping changes were made in 1.0, but I hope that automatic let-block-wrapping idea that Stefan mentioned gets implemented and released ASAP. It may even be worth making a 1.01 bug fix release just for that. Because Iām pretty sure I lost a third of my potential new Julia recruits just because of this.
You really cannot win. We used to get so much flack for the scope rules being slightly complicated specifically to make this case work in an intuitive way. So we fix that and now we have this. In any case, I think that the current behavior, though less convenient, is the right one since it is the one that is statically resolvable. We should experiment with the automatic let wrapping in the REPL, however.
Can that (let wrapping) be done in 1.0.1, instead of waiting for 1.1?
It is only the REPL
I am a big fan of the new behavior, the old āspooky action at a distanceā scoping rules was one of the biggest warts on a beautiful language, thanks for taking the hard decision to fix this in v1.0.0ā¦
1- there were some very long discussions here and on github. Does anybody know if any conclusion has been reached?
2 - I was wondering if the global declaration and the explicit reference creates any (significant) overhead considering that itās looped over at every iteration?
3 - if a solution is still open for discussion, maybe something inspired by PHPās lambdas syntax would work? In julia it could look like:
somevar, someothervar = 10, 100
for i in 1:1_000 accessing (somevar, someothervar)
# do stuff with somevar and someothervar
end
The accessing block would be optional. It could start as syntactic sugar for the ugly global as itās more readable, in my opinion. Plus, as a less imperative approach, later on, the underlying implementation could be optimised at compiler level.
I can no longer even make the most basic iterations work switching from Julia 0.x to 1.x - probably because I donāt understand the computer science behind the ātweak.ā
You say that this is a mere " inconvenience." To the beginner, this is inconvenient in the same way as a broken condom is inconvenient in regards to preventing pregnancy.
I am shattered. With this " tweak", my love affair with Julia (0.x) has suddenly turned into a nightmare. I am back to trying to turn me into a computer scientist, with Julia (1.x)? Itās not going to happen.
I was doing straightforward scientific programming Julia 0.x with no issues, ever. Now, it seems that Iāve run into a concrete wall with this Julia 1.x. " issue."
Please tell me that I can get over this in a day or two by pointing me to THE helpful resource that will help make me whole again. Save me from the truly inconvenient jaws of Mathematica.