Scope of variable in if in loop

from my understanding, “if” doesn’t create new scope, so the variable “b” should be local variable in for loop. So why there is an error saying b is not found in the “else” ?

function f1(a)
  for i = 1:2
    if i ==1
      b = a +1
      println("a = $a, b = $b")
    else
      println("b = $b")
    end
 end
end
f1(2)
a = 2, b = 3
ERROR: UndefVarError: b not defined

I think because the compiler isn’t able to figure out that the i==1 branch of the if (which defines b) always executes first, so at compile-time it thinks that it’s possible that b is not defined yet in the else branch. See below for the correct answer.

2 Likes

The behavior you see is the expected behavior. The if statement does not create a new scope, but the for creates a new scope for each iteration. So b will never be defined inside any loop besides the first. You need to declare it one scope above for your code to work (i.e., outside the for).

I wrote a better answer to a very similar question in the past: I thought I understood "pass-by-sharing" in Julia until I found this - #19 by Henrique_Becker

12 Likes

Thanks for the answer. I assume if I want to improve performance, it’s better to declare variables used in for loop?

1 Like

No, variable declarations are not generally needed for performance. Just make sure your variable usage is type-stable (and read the other performance tips).

1 Like

Maybe there is a confusion here. If the variable in case is was not a scalar or some other immutable, certainly you should create it outside the loop and mutate it inside to avoid creating a new mutable variable at every iteration.

1 Like

Thank you! this is very useful!

To be clear, the variable in the code above is an Int (an immutable type)— there is no cost to “creating” new Int variables in every iteration vs declaring them outside the loop.

1 Like

Yes, when you said immutable or mutable I thought about arrays (which is the variable i actually use), declaring or not really makes difference.