Local Scope Confusion


#1

I have a very basic question that I can’t wrap my head around. I’m having some trouble understanding the following behavior:

for i in 1:2
    if i == 1
        a = 1
    else
        a += 1
    end
end
# ERROR: UndefVarError: a not defined

I expect that a should be defined on the first iteration of the loop and, since it belongs to the for loop’s scope, it should be available on the second iteration of the loop.

Sorry for such a basic question and thanks!


#3

The docs say that if blocks do not have their own scope… And I figured that a will only be set on the first iteration and won’t be reset in other iterations.

For example this does what I expect:

a = 456 # Dummy value
for i in 1:2
    if i == 1
        a = 1
    else
        a += 1
    end
end
# a = 2

This does make it seem like an if block has its own scope which is opposite of what the docs say…


#4

The if blocks do not create a new scope, as noted in the third paragraph of the doc . So really the only problem with your code is that a was not defined before for began, and you fixed that in your second example.

I’d set a=0 to be clearer, but you fixed it. You can also put little println("i = $i a = $a") statements in the loop to help you see what it’s doing.


#5

Right, so I guess the core of my question is to which scope does a belong in my first example? If it belongs to the for loop’s scope, why is it not visible in the second iteration? Are for loop variables only in scope for a single iteration?


#6

In the second example, a is in the global (before-for) scope, just to cover that one.

In the first example, a didn’t exist when for started. So, when i == 1 it creates a local a = 1, then destroys it at the end of that iteration. On the next i it tries to a += 1 but there is no a in existence anymore. So, you could say that a is in the scope of the inside of each for loop, but not outside of the loop.


#7

Okay, I understand. Thank you! I assumed that the for loop variables would be destroyed once the entire loop completed rather than after each iteration.