# Strange loop behavior when assigning variable within loop

**URL:** <https://discourse.julialang.org/t/strange-loop-behavior-when-assigning-variable-within-loop/21620>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [March 8, 2019, 4:21am UTC](https://discourse.julialang.org/t/strange-loop-behavior-when-assigning-variable-within-loop/21620 "2019-03-08T04:21:16Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![mboratko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mboratko/32/5377_2.png) [@mboratko](https://discourse.julialang.org/u/mboratko)\
**Post date:** [March 8, 2019, 4:21am UTC](https://discourse.julialang.org/t/strange-loop-behavior-when-assigning-variable-within-loop/21620/1 "2019-03-08T04:21:16Z")

</div>

I’m confused about the following behavior:

```julia
julia> a = 2019
2019

julia> for i in 1:2
           println(i)
           println(a)
           a = 57
       end
1
ERROR: UndefVarError: a not defined
Stacktrace:
 [1] top-level scope at ./REPL[2]:3 [inlined]
 [2] top-level scope at ./none:0

```

I would have thought that this would have printed:

```julia
1
2019
2
57

```

Can someone explain where my thinking is going wrong?

---

<div class="post-metadata">

**Author:** ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)\
**Post date:** [March 8, 2019, 4:38am UTC](https://discourse.julialang.org/t/strange-loop-behavior-when-assigning-variable-within-loop/21620/2 "2019-03-08T04:38:28Z")

</div>

The relevant section in [the manual is here](https://docs.julialang.org/en/latest/manual/variables-and-scoping/#Local-Scope-1). To be specific:

> In a local scope, all variables are inherited from its parent global scope block unless:
> 
> - an assignment would result in a modified _global_ variable, or

In other words, since `a = 57` is an assignment that would result in a modified global variable, `a` is not inherited from the global REPL scope, so trying to access it with `println(a)` results in an `a not defined` error.

If you want the output you suggest, you can use `global a = 57` to change the global variable.

---

<div class="post-metadata">

**Author:** ![mboratko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mboratko/32/5377_2.png) [@mboratko](https://discourse.julialang.org/u/mboratko)\
**Post date:** [March 8, 2019, 4:42am UTC](https://discourse.julialang.org/t/strange-loop-behavior-when-assigning-variable-within-loop/21620/3 "2019-03-08T04:42:24Z")

</div>

Hmm, strange, on Juliabox using 1.0.3 this works the way I would expect though:  
 ![image](https://global.discourse-cdn.com/julialang/original/3X/b/5/b5d5483b71915930b8c8e78c64a614e091dd6663.png)

It’s only on my machine it has this error.

I ran it with `--startup-file=no` and even renamed the startup file to be sure it was a vanilla REPL.

~~Any suggestions?~~ Why would this behavior differ between different installs of the same version of Julia?

---

<div class="post-metadata">

**Author:** ![mboratko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mboratko/32/5377_2.png) [@mboratko](https://discourse.julialang.org/u/mboratko)\
**Post date:** [March 8, 2019, 4:51am UTC](https://discourse.julialang.org/t/strange-loop-behavior-when-assigning-variable-within-loop/21620/4 "2019-03-08T04:51:26Z")

</div>

Following up: looks like this also works in my local Jupyter install. Here’s a screenshot from an IJulia console session:  
 ![image](https://global.discourse-cdn.com/julialang/original/3X/6/b/6bec755d830714361590c65717d5c40b02b9ef10.png)

Seems like IJulia and the Julia REPL treat these differently for some reason?

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [March 8, 2019, 5:01am UTC](https://discourse.julialang.org/t/strange-loop-behavior-when-assigning-variable-within-loop/21620/5 "2019-03-08T05:01:45Z")

</div>

This is the “soft global scope” problem [https://github.com/JuliaLang/julia/issues/28789](https://github.com/JuliaLang/julia/issues/28789).

I believe the behavior in jupyter is different to the REPL because jupyter uses [https://github.com/stevengj/SoftGlobalScope.jl](https://github.com/stevengj/SoftGlobalScope.jl) as a workaround for the somewhat unintuitive behavior of the new scoping rules in julia-1.0. (The rules changed only for code executed at “top level” - ie outside a function.)

There’s been a lot of discussion on this forum about this particular issue which you can find if you search for things like “soft global scope”.

---

<div class="post-metadata">

**Author:** ![mboratko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mboratko/32/5377_2.png) [@mboratko](https://discourse.julialang.org/u/mboratko)\
**Post date:** [March 8, 2019, 5:11am UTC](https://discourse.julialang.org/t/strange-loop-behavior-when-assigning-variable-within-loop/21620/6 "2019-03-08T05:11:06Z")

</div>

I guess shoutout to this comment, as that is exactly what happened in this case:

> <https://github.com/JuliaLang/julia/issues/28789#issuecomment-414745619>
>
> \### Example 1
> 
> This came up with a student who upgraded from 0.6 to 1.0 direct…ly, so never even got a chance to see a deprecation warning, let alone find an explanation for new behavior:
> 
> \`\`\`julia
> julia\> beforefor = true
> true
> 
> julia\> for i in 1:2
> beforefor = false
> end
> 
> julia\> beforefor # this is surprising bit
> true
> 
> julia\> beforeif = true
> true
> 
> julia\> if 1 == 1
> beforeif = false
> end
> false
> 
> julia\> beforeif # Another surprise!
> false
> 
> julia\> function foo()
> infunc = true
> for i in 1:10
> infunc = false
> end
> @show infunc
> end
> foo (generic function with 1 method)
> 
> julia\> foo() # "I don't get this"
> infunc = false 
> \`\`\`
> 
> \### Example 2
> 
> \`\`\`julia
> julia\> total\_lines = 0
> 0
> 
> julia\> list\_of\_files = \["a", "b", "c"\]
> 3-element Array{String,1}:
> "a"
> "b"
> "c"
> 
> julia\> for file in list\_of\_files
> # fake read file
> lines\_in\_file = 5
> total\_lines += lines\_in\_file
> end
> ERROR: UndefVarError: total\_lines not defined
> Stacktrace:
> \[1\] top-level scope at ./REPL\[3\]:4 \[inlined\]
> \[2\] top-level scope at ./none:0
> 
> julia\> total\_lines # This crushs the students willingness to learn
> 0
> \`\`\`
> 
> I "get" why this happens in the sense that I think I can explain, with sufficient reference to the arcana in the manual about what introduces scopes and what doesn't, but I think that this is problematic for interactive use.
> 
> In example one, you get a silent failure. In example two, you get an error message that is very there-is-no-spoon. Thats roughly comparable to some Python code I wrote in a notebook at work today.
> 
> I'm not sure what the rules are in Python, but I do know that generally you can't assign to things at the global scope without invoking global. But at the REPL it does work, presumably because at the REPL the rules are different or the same logic as if they were all are in the scope of function is applied.
> 
> I can't language-lawyer the rules enough to propose the concrete change I would like, and based on Slack this isn't even necessarily perceived as an issue by some people, so I don't know where to go with this except to flag it.
> 
> Cross-refs:
> \#19324
> https://discourse.julialang.org/t/repl-and-for-loops-scope-behavior-change/13514
> https://stackoverflow.com/questions/51930537/scope-of-variables-in-julia
