# Loop Scope works differently for Int and Arrays. Why?

**URL:** <https://discourse.julialang.org/t/loop-scope-works-differently-for-int-and-arrays-why/28172>\
**Category:** New to Julia\
**Created:** [August 29, 2019, 4:14pm UTC](https://discourse.julialang.org/t/loop-scope-works-differently-for-int-and-arrays-why/28172 "2019-08-29T16:14:34Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![BMval](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bmval/32/7647_2.png) [@BMval](https://discourse.julialang.org/u/BMval)\
**Post date:** [August 29, 2019, 4:14pm UTC](https://discourse.julialang.org/t/loop-scope-works-differently-for-int-and-arrays-why/28172/1 "2019-08-29T16:14:34Z")

</div>

Loop Scope works differently for Int and Arrays. Why?

Here is an example. Array w is changed inside the loop, but variable w isn’t.

> w=zeros(2)  
> println(w)  
> for i=1:2  
> w[i]=i  
> end  
> println(w)
> 
> q=0  
> println(q)  
> for i=1:2  
> q=i  
> end  
> println(q)

---

<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:** [August 29, 2019, 4:29pm UTC](https://discourse.julialang.org/t/loop-scope-works-differently-for-int-and-arrays-why/28172/2 "2019-08-29T16:29:48Z")

</div>

Long story, but if you are just getting started the easiest way to deal with this is to:

- Use Jupyter for exploratory script-style code. It _doesn’t have this issue_
- Wrap anything that uses `for` loops in a function otherwise, which also doesn’t have this issue.

If you follow that advice, you will never see this problem again. Hopefully at some point things will be a little more intuitive. If you want more context, there are a lot of threads on discourse to discuss.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 29, 2019, 4:34pm UTC](https://discourse.julialang.org/t/loop-scope-works-differently-for-int-and-arrays-why/28172/3 "2019-08-29T16:34:17Z")

</div>

No, this is not the scoping issue, this about assignment vs mutation. Or maybe it’s both?

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [August 29, 2019, 4:36pm UTC](https://discourse.julialang.org/t/loop-scope-works-differently-for-int-and-arrays-why/28172/4 "2019-08-29T16:36:34Z")

</div>

There’s two things going on here. The first is that for the array case, you’re modifying the existing array, not rebinding `w` to point to a new array each loop iteration (which is what’s happening in the integer case). So there’s a different kind of operation going on between the two examples (modifying an object vs rebinding a variable to point at a new object).

The second thing is that for loops introduce a local scope, which means variables you bind in that scope are by default local variables, and don’t overwrite global variables such as `q`. To avoid this, in the loop you can declare `global q` in the loop to say that you want your use of `q` to refer to the global variable when you rebind it. Another option (because using global variables is slow) is to put the for loop in a function `f` and use `q = f(q)`.

(Note also Jupyter uses a package to emulate top-level for loops being in global scope; if you don’t know that it can be confusing when you see different behavior between Jupyter and the repl).

Edit: I started writing this before seeing the other replies, but I think we’re all saying more-or-less the same thing

---

<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:** [August 29, 2019, 4:41pm UTC](https://discourse.julialang.org/t/loop-scope-works-differently-for-int-and-arrays-why/28172/5 "2019-08-29T16:41:40Z")

</div>

They are often connected in practice. Although are you saying that I am wrong, and that the behavior is the same in the REPL and Jupyter in this case?

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [August 29, 2019, 4:44pm UTC](https://discourse.julialang.org/t/loop-scope-works-differently-for-int-and-arrays-why/28172/6 "2019-08-29T16:44:32Z")

</div>

The reason the array case is different than the integer case is assignment vs mutation; The reason that difference causes a different behavior here is the local scope of the for loops treats those two things differently (allows mutation of global variables, but uses local variables on assignment)

---

<div class="post-metadata">

**Author:** ![BMval](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bmval/32/7647_2.png) [@BMval](https://discourse.julialang.org/u/BMval)\
**Post date:** [August 29, 2019, 4:49pm UTC](https://discourse.julialang.org/t/loop-scope-works-differently-for-int-and-arrays-why/28172/7 "2019-08-29T16:49:50Z")

</div>

Thank you.  
How Can I modify integer like array, not to rebind it

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [August 29, 2019, 4:54pm UTC](https://discourse.julialang.org/t/loop-scope-works-differently-for-int-and-arrays-why/28172/8 "2019-08-29T16:54:21Z")

</div>

Integers are immutable, meaning they can’t be modified, but one option is to put the integer in a mutable container and use that. For example, `q = Ref(1)` stores 1 in a container, and the value can be accessed or changed by doing `q[]` or `q[] = 2`, etc. This is just like in the array case where you index to modify the array.

Edit: but often you don’t really need that, and it’s better to just use functions like I wrote in the last post.

---

<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:** [August 29, 2019, 4:55pm UTC](https://discourse.julialang.org/t/loop-scope-works-differently-for-int-and-arrays-why/28172/9 "2019-08-29T16:55:44Z")

</div>

> [@BMval](#):
>
> How Can I modify integer like array, not to rebind it

It may depend on what you are trying to do. If you are just trying to code an algorithm up along the lines of what you have above, then follow my advice: use jupyter or put it in a function. You won’t need to worry about this issue.

If you “really” want to modify it in place, then you can use that fancy `Ref` stuff… but it is unlikelky that you need it.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 29, 2019, 4:56pm UTC](https://discourse.julialang.org/t/loop-scope-works-differently-for-int-and-arrays-why/28172/10 "2019-08-29T16:56:01Z")

</div>

> [@jlperla](#):
>
> Although are you saying that I am wrong

My knee-jerk reaction was that you were wrong, but then I realized it was both things.

---

<div class="post-metadata">

**Author:** ![BMval](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bmval/32/7647_2.png) [@BMval](https://discourse.julialang.org/u/BMval)\
**Post date:** [August 29, 2019, 4:56pm UTC](https://discourse.julialang.org/t/loop-scope-works-differently-for-int-and-arrays-why/28172/11 "2019-08-29T16:56:09Z")

</div>

Thank you for good explanation.  
One more, please.

So why inside the function there are other rules.  
I hope function it’s like small code, or main code is like the main function.  
An example result will be “2” no “10”.

> q=0  
> println(q)  
> for i=1:2  
> q=i  
> end  
> println(q)  
> function foo(arg)  
> arg=10  
> for i=1:2  
> arg=i  
> end  
> return arg  
> end  
> println(foo(q))

---

<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:** [August 29, 2019, 4:58pm UTC](https://discourse.julialang.org/t/loop-scope-works-differently-for-int-and-arrays-why/28172/12 "2019-08-29T16:58:00Z")

</div>

> [@BMval](#):
>
> So why inside the function there are other rules.

An intuitive answer to this probably depends on what other programming language you are coming from, and your level of familiarity with scoping rules in general.

This is an issue that only hits you (\> Julia 0.6 as it didn’t use to be an issue) if you write top level code with for loops outside of jupyter. If you don’t do that, then the Julia scoping rules are very intuitive.

---

<div class="post-metadata">

**Author:** ![BMval](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bmval/32/7647_2.png) [@BMval](https://discourse.julialang.org/u/BMval)\
**Post date:** [August 29, 2019, 4:59pm UTC](https://discourse.julialang.org/t/loop-scope-works-differently-for-int-and-arrays-why/28172/13 "2019-08-29T16:59:44Z")

</div>

Thank you for Ref()  
I got is, I know it from C++. I would like to use Ref in future

---

<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:** [August 29, 2019, 5:00pm UTC](https://discourse.julialang.org/t/loop-scope-works-differently-for-int-and-arrays-why/28172/14 "2019-08-29T17:00:47Z")

</div>

> [@BMval](#):
>
> would like to use Ref in future

This is _almost never_ what you want to do. It would be like only modifying integers through pointers, which leaves out all sorts of optimizations and clutters your code.

Just put your code in a function.

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [August 29, 2019, 5:09pm UTC](https://discourse.julialang.org/t/loop-scope-works-differently-for-int-and-arrays-why/28172/15 "2019-08-29T17:09:29Z")

</div>

Functions introduce local scopes just like for loops, and local scopes inherit all the variables of parent local scopes (see here: [https://pkg.julialang.org/docs/julia/THl1k/1.1.1/manual/variables-and-scoping.html#Local-Scope-1](https://pkg.julialang.org/docs/julia/THl1k/1.1.1/manual/variables-and-scoping.html#Local-Scope-1)). I think the manual does a pretty good job explaining it all, but there’s a lot of details.

---

<div class="post-metadata">

**Author:** ![BMval](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bmval/32/7647_2.png) [@BMval](https://discourse.julialang.org/u/BMval)\
**Post date:** [August 29, 2019, 5:19pm UTC](https://discourse.julialang.org/t/loop-scope-works-differently-for-int-and-arrays-why/28172/17 "2019-08-29T17:19:21Z")

</div>

Thank you.  
I got it.

Although I prefer the local scope, don’t have the right to modify parent scope, since why do I need a scope inside the scope.

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [August 29, 2019, 6:55pm UTC](https://discourse.julialang.org/t/loop-scope-works-differently-for-int-and-arrays-why/28172/18 "2019-08-29T18:55:36Z")

</div>

Actually, you can modify the parent scope, unless the parent scope is module-global.  
To ensure everything is wrapped into a local scope, use `let`:

```julia
julia> q=0
0

julia> println(q)
0

julia> for i=1:2
       q=i
       end

julia> println(q)
0

julia> let q=0
       println(q)
       for i=1:2 q=i end
       println(q)
       end
0
2

```
