Nested for loops, UndefVarError


#1

Hi everyone, I have a pretty basic question. The following code is giving me an UndefVarError, and I can’t understand why.

n=1
for i in 1:3
    for j in 4:5
        n += 1
    end
end
print(n)

The line incrementing n is throwing an UndefVarError: n not defined.

I know I can avoid the problem by enclosing the code in a let, but that seems to be the wrong fix, so I am wondering what I am missing here (probably about scope).

Thanks!


#2

The variable n is a global variable and you thus need to use global n += 1 to modify it from local scope (inside the for loop).


#3

And that’s why enclosing it in a let works — it does the opposite thing and makes n a local variable (local to the let), and local variables can be modified from other nested local scopes.


#4

I see, thanks. Right, in fact, there was no need for the example to have nested for loops.

It seems to be a somewhat counterintuitive feature of Julia. I would have guessed that the local scope of the for loop would inherit the global variables.

Also, running this code on JuliaBox, this issue does not arise for some reason, which made it hard to figure out what is happening. Why doesn’t the error get thrown there?


#5

See also https://github.com/JuliaLang/julia/issues/28789

… in IJulia/Jupyter/JupyterLab, and soon in the REPL and other interactive contexts, the plan is for Julia to (re-)enable “soft” scoping rules so that you don’t need such global declarations for interactive exploration.

Once you move to non-interactive contexts, you should start putting code into functions and stop modifying global variables, in which case the need for global keywords becomes less relevant.


#6

It does indeed inherit the globals, but the globals are allowed to be shadowed by local variables that get introduced in the scope by an assignment.


#7

Thanks again. I read the thread on GitHub, and I would (respectfully) agree that this behavior is definitely not what first-time users expect (who are used to coding in Python and C++). I’m too new of a user and too late to the table to add anything new or useful to the discussion for v1, but I hope that for v2, this will be resolved.


#8

Yet another one of these scoping posts. I’m glad that we are going to be reverting back to a “soft” scope. Does anyone know a timeline for that (is it salted for v2.0)?


#9

I decided to use module block and I am happy with it.


#10

The plan is to use soft scope for interactive environments only. IJulia (Jupyter, JupyterLab) already does this, and the REPL will be changed in Julia 1.1.


#11

I have recently bumped this counterintuitive (as a Python programmer) behaviour in REPL. I can bet many Julia beginners will raise the same question I had. Appreciate if it is changed when Julia 1.1 rolls out.