# Local scope in for loops AGAIN

**URL:** <https://discourse.julialang.org/t/local-scope-in-for-loops-again/45899>\
**Category:** General Usage\
**Created:** [September 1, 2020, 2:32pm UTC](https://discourse.julialang.org/t/local-scope-in-for-loops-again/45899 "2020-09-01T14:32:39Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![sandeep\_prakash](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sandeep_prakash/32/17620_2.png) [@sandeep\_prakash](https://discourse.julialang.org/u/sandeep_prakash)\
**Post date:** [September 1, 2020, 2:32pm UTC](https://discourse.julialang.org/t/local-scope-in-for-loops-again/45899/1 "2020-09-01T14:32:39Z")

</div>

Hi,  
New to Julia from MATLAB. I’ve been reading up on the local variable scope rules in Julia, but fail to understand the behaviour i see in the following example

> Example code

```
u0 = 10 #The global scope variable

for k in 1:10
    local local_u
    
    #In the first iteration, local_u reads from the global variable
    if k == 1           
        local_u = copy(u0)
    end

    #My main function call goes here - returns uk which i want to use in next iteration
    uk = k*10*local_u

    #Reassigning local_u to the result from the current iteration
    local_u = copy(uk)
    println("At end of iteration ", k, " local_u is ", local_u)
end

```

I can see that it goes through 1 iteration, but then throws the error when trying to execute.  
I get the error message → UndefVarError: local\_u not defined

So my Question is - Does the local variable (local\_u) get destroyed after every iteration in the for loop ? Or am i misunderstanding something here.

Any help appreciated.

---

<div class="post-metadata">

**Author:** ![fbanning](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fbanning/32/14972_2.png) [@fbanning](https://discourse.julialang.org/u/fbanning)\
**Post date:** [September 1, 2020, 2:40pm UTC](https://discourse.julialang.org/t/local-scope-in-for-loops-again/45899/2 "2020-09-01T14:40:12Z")

</div>

You’re recreating `local local_u` in every iteration of the loop, thus overwriting its previous value. The behaviour you experience is therefore to be expected.

Why not just wrap it in a function?

```julia
u = 10 # global scope variable

function foo(u)
    for k in 1:10
        u = k*10*u # could also write u *= k*10
        println("At the end of iteration $k local u is $u")
    end
end

foo(u)

```

This is much simpler and you don’t have to deal with the local keyword, reassigning, copying or anything else.

---

<div class="post-metadata">

**Author:** ![sandeep\_prakash](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sandeep_prakash/32/17620_2.png) [@sandeep\_prakash](https://discourse.julialang.org/u/sandeep_prakash)\
**Post date:** [September 1, 2020, 3:04pm UTC](https://discourse.julialang.org/t/local-scope-in-for-loops-again/45899/3 "2020-09-01T15:04:56Z")

</div>

> [@fbanning](#):
>
> You’re recreating `local local_u` in every iteration of the loop, thus overwriting its previous value. The behaviour you experience is therefore to be expected.

Sorry, i do not fully understand. Then removing this line from my code should have solved th issue right? Even when i remove the line “Local local\_u”, i get the same behaviour and error. It should be able to access the variable local\_u from iteration k=1 during iteratio k=2 in this case, but doesn’t look like it.

> [@fbanning](#):
>
> Why not just wrap it in a function?

My original code is trying to solve an Optimal Control Problem and simulate the plant, which are already in their own functions. I just put in `k*10*local_u` as a dummy line here instead of my function call. I am using the for loop to step through time in the main file, and hence did not want to wrap in a seperate function again.

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [September 1, 2020, 3:12pm UTC](https://discourse.julialang.org/t/local-scope-in-for-loops-again/45899/4 "2020-09-01T15:12:58Z")

</div>

OP, here is an MWE

```julia
julia> for i in 1:10
       if i == 1
           a = 2
       end
       
       @show a
       end

```

This will throw the same error.

The way to think about this is that when you say `a = 1`, that assignment only exists for the first iteration of the loop. The other iterations of the loop don’t know that a variable `a` exists since it isn’t created in those other iterations.

If you want it to persist, you need to define it outside the loop. This is certainly a bit of a pain before `1.5` but now it works “as expected” when copied and pasted into the REPL.

---

<div class="post-metadata">

**Author:** ![fbanning](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fbanning/32/14972_2.png) [@fbanning](https://discourse.julialang.org/u/fbanning)\
**Post date:** [September 1, 2020, 3:14pm UTC](https://discourse.julialang.org/t/local-scope-in-for-loops-again/45899/5 "2020-09-01T15:14:21Z")

</div>

> [@sandeep\_prakash](#):
>
> I just put in `k*10*local_u` as a dummy line here instead of my function call. I am using the for loop to step through time in the main file, and hence did not want to wrap in a seperate function again.

My approach would remain the same. Just write `u = bar(u)` instead of `u = k*10*u`. I don’t see any problem with that.

---

<div class="post-metadata">

**Author:** ![sandeep\_prakash](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sandeep_prakash/32/17620_2.png) [@sandeep\_prakash](https://discourse.julialang.org/u/sandeep_prakash)\
**Post date:** [September 1, 2020, 3:42pm UTC](https://discourse.julialang.org/t/local-scope-in-for-loops-again/45899/6 "2020-09-01T15:42:55Z")

</div>

> [@pdeffebach](#):
>
> when you say `a = 1` , that assignment only exists for the first iteration of the loop

Oh, that’s too bad. My mistake was that i misunderstood that the local variables were available until the “for loop” terminates. Thanks for the correction.

In this case, then I will use this approach then,

```julia
a = 1
for i in 1:10
    global a1

   a_temp = i*10*a #Get the next step of a. to be used in next iteration
   
    @show a_temp
    a = a_temp #assigning a_temp to be used in next iteration
    
end

```

If i may ask a followup question.  
The line `a1 = a_temp` seems to be working instead of me having to use `a = copy(a_temp)`.

Am i right in my understanding then that  
`a = a_temp` binds the variable names to the same underlying number, but when a\_temp is destroyed at the end of iteration 1, the global variable `a` is able to retain the same value and does not end up cleared (even though the underlying local variable was cleared out)

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [September 1, 2020, 3:44pm UTC](https://discourse.julialang.org/t/local-scope-in-for-loops-again/45899/7 "2020-09-01T15:44:34Z")

</div>

yes that is correct.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [September 1, 2020, 3:56pm UTC](https://discourse.julialang.org/t/local-scope-in-for-loops-again/45899/8 "2020-09-01T15:56:47Z")

</div>

Probably one thing more to note, is that arrays work differently than scalars, and the `copy` function plays an important role there:

```julia
julia> a = 1 ; b = [1, 1] ;

julia> for i in 1:2
           a2 = a
           b2 = b 
           a2 = 0
           b2[1] = 0
       end

julia> a
1

julia> b
2-element Array{Int64,1}:
 0
 1

```

Note that the value in the first position of the `b` vector changes, but the value of `a` does not, the variable `a2` is local to the loop. Now using copy:

```julia
julia> a = 1 ; b = [1, 1] ;

julia> for i in 1:2
           a2 = copy(a) # this is redudant for a scalar
           b2 = copy(b)
           a2 = 0
           b2[1] = 0
       end

julia> a
1

julia> b
2-element Array{Int64,1}:
 1
 1

julia> b2
ERROR: UndefVarError: b2 not defined

```

For the scalar, this is the same as before, but now `b2` is a vector local to the loop, occupying a different space in memory, and altering its values do not alter the original `b`.

---

<div class="post-metadata">

**Author:** ![jlperla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlperla/32/34332_2.png) [@jlperla](https://discourse.julialang.org/u/jlperla)\
**Post date:** [September 1, 2020, 4:12pm UTC](https://discourse.julialang.org/t/local-scope-in-for-loops-again/45899/9 "2020-09-01T16:12:49Z")

</div>

> [@lmiq](#):
>
> `global a # not required anymore in 1.5`

That isn’t exactly true. Right now:

- It isn’t required in Jupyter (and it never has been).
- It (\>= 1.5) isn’t required in the (normal) REPL or execute the code through any IDE that sends text to a normal REPL.
- It is required if you use the REPL in vscode
- It is required if you run it as a `.jl` file with include, etc.

My advice: stick to jupyter for this sort of thing where there are any top-level loops, and move to functions as soon as you no longer want to use jupyter

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [September 1, 2020, 4:16pm UTC](https://discourse.julialang.org/t/local-scope-in-for-loops-again/45899/10 "2020-09-01T16:16:32Z")

</div>

Yes, I fixed that already. In that context it was never required.

What changed is that if you need to assign a new value to the global variable, in 1.5 or greater you do not need to add the `global` anymore when using the REPL.

```julia

julia> a = 0
0

julia> for i in 1:2
          global a # not required anymore in 1.5
          a = a + 1
       end

```

---

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [September 1, 2020, 4:47pm UTC](https://discourse.julialang.org/t/local-scope-in-for-loops-again/45899/11 "2020-09-01T16:47:39Z")

</div>

> [@sandeep\_prakash](#):
>
> In this case, then I will use this approach then,
> 
> ```julia
> a = 1
> for i in 1:10
> global a1
> 
> a_temp = i*10*a #Get the next step of a. to be used in next iteration
>    
> @show a_temp
> a = a_temp #assigning a_temp to be used in next iteration
>     
> end
> 
> ```

I really think what you want is:

```julia
function calculatemything(a)
   for i in 1:10
      ...
   end
  return stuff
end

calculatemything(1)

```

---

<div class="post-metadata">

**Author:** ![lungben](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lungben/32/12314_2.png) [@lungben](https://discourse.julialang.org/u/lungben)\
**Post date:** [September 1, 2020, 4:47pm UTC](https://discourse.julialang.org/t/local-scope-in-for-loops-again/45899/12 "2020-09-01T16:47:50Z")

</div>

I would strongly advice to put your loop into a function, as @fbanning suggested, unless you are looping over very few elements.  
The reason for this is that global variables are not type-stable and therefore you are getting bad performance - see the very first performance tip in [Performance Tips · The Julia Language](https://docs.julialang.org/en/v1/manual/performance-tips/)
