# I thought I understood "pass-by-sharing" in Julia until I found this

**URL:** <https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897>\
**Category:** General Usage\
**Created:** [September 19, 2020, 5:59am UTC](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897 "2020-09-19T05:59:11Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)\
**Post date:** [September 19, 2020, 5:59am UTC](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897/1 "2020-09-19T05:59:11Z")

</div>

Here is a snippet from “Julia 1.0 Programming Complete Reference Guide”:

```julia
anon = Array{Any}(undef, 2)
for i = 1:2
  anon[i] = ()-> println(i)
  i += 1
end

```

Can someone explain or point me to explanation why

```julia
julia> anon[1]()
2

```

not

```julia
julia> anon[1]()
1

```

as I expected. The manual reads: _Function arguments themselves act as new variable bindings (new locations that can refer to values), but the values they refer to are identical to the passed values._ Argument `i` is bound to value `1` when `anon[1]()` is defined, so the _passed value_ is `1`. What does `location that can refer to values` mean? Is there a more formal definition of these concepts somewhere?

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [September 19, 2020, 6:23am UTC](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897/2 "2020-09-19T06:23:52Z")

</div>

And:

```julia
julia> anon[2]()
3

```

The reason seems to be that `i` is a boxed variable:

```julia
julia> anon[1].i
Core.Box(2)

```

If you use a `let` block you should get the what you’re going for:

```julia
julia> for i = 1:2
         let i = i 
             anon[i] = ()-> println(i)
         end
         i += 1
       end

julia> anon[1]()
1

```

This anonymous function is a struct of bitstypes, not boxed variables. I guess you need to be careful with anonymous functions ~~in global scope~~ Edit: in scopes where the variables are changed, as they seem similar but are not really the same thing as anonymous functions in for loop/let block scope where the variable is not changed.

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [September 19, 2020, 6:29am UTC](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897/3 "2020-09-19T06:29:10Z")

</div>

I guess this really highlights your questions in the other thread about variables being label/boxes - it isn’t totally clear sometimes - not in the language generally, but in the transfer of code from different scopes ~~from global/REPL~ scope to functions~~.

---

<div class="post-metadata">

**Author:** ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)\
**Post date:** [September 19, 2020, 6:33am UTC](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897/4 "2020-09-19T06:33:54Z")

</div>

> [@Raf](#):
>
> be careful with anonymous functions in global scope,

But when I move this snippet to a local scope, behaviour is the same:

```julia
let
  anon = Array{Any}(undef, 2)
  for i = 1:2
    anon[i] = ()-> println(i)
    i += 1
  end

  anon[1]()
  anon[2]()
end
.....
2
3

```

Where is syntax like `anon[1].i` described? A function has fields?

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [September 19, 2020, 6:44am UTC](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897/5 "2020-09-19T06:44:02Z")

</div>

Hmm yeah. So the for loop scope is always captured as a boxed variable.

~~But if you do it with map instead~~ :

```julia
julia> let
         anon = map(1:2) do i
             ()-> println(i)
             i += 1
         end
         anon[1]()
         anon[2]()
       end
1
2

```

Oops I missed the key line- it’s the same with map too:

```julia
julia> let
        anon = map(1:2) do i
            f = ()-> println(i)
            i += 1
            f
        end
        anon[1]()
        anon[2]()
       end
2
3

```

Someone more familiar with internals would have to answer here.

But anonymous functions are really _functors_ underneath. I think the fields are an implementation detail, not something you’re mean to mess with so they aren’t really discussed.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 19, 2020, 7:22am UTC](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897/6 "2020-09-19T07:22:06Z")

</div>

This is explained in detail in [the docs for let blocks](https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Let-Blocks). With examples. Search for the part starting with

> Here is an example where the behavior of `let` is needed:

Please

1. **Do read the manual.** It is written to be read and a lot of work went into it to explain details like this.

2. Try to give up all the metaphors from the C/C++ world (“pass by sharing”) etc. They will just distract you from understanding Julia.

---

<div class="post-metadata">

**Author:** ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)\
**Post date:** [September 19, 2020, 7:29am UTC](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897/7 "2020-09-19T07:29:24Z")

</div>

> [@Tamas\_Papp](#):
>
> give up all the metaphors from the C/C++ world (“pass by sharing”)

This metaphor does not exist in C/C++ world, it is taken straight from Julia manual ([Functions · The Julia Language](https://docs.julialang.org/en/v1/manual/functions/#Argument-Passing-Behavior)):

_Julia function arguments follow a convention sometimes called “pass-by-sharing”, which means that values are not copied when they are passed to functions. Function arguments themselves act as new variable bindings (new locations that can refer to values), but the values they refer to are identical to the passed values._

I read the manual trying to find more precise definition of these metaphors, but I failed so far.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 19, 2020, 7:36am UTC](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897/8 "2020-09-19T07:36:22Z")

</div>

Your example has nothing to do with argument passing; it is about scope (see the link).

FWIW, I think that the whole call-by-X discussion is just confusing as the Xs are not clearly defined — if anything, Julia is call-by-value. But, again, this is a red herring here.

---

<div class="post-metadata">

**Author:** ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)\
**Post date:** [September 19, 2020, 7:41am UTC](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897/10 "2020-09-19T07:41:32Z")

</div>

> [@Tamas\_Papp](#):
>
> call-by-X discussion is just confusing as the Xs are not clearly defined

Parameter passing has to be defined somewhere, at least in the minds of Julia implementers. I’m looking for this definition in order to avoid frequent surprises.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 19, 2020, 7:47am UTC](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897/11 "2020-09-19T07:47:38Z")

</div>

It _is_ well defined, but the problem is that the terminology isn’t.

But it is much, much simpler than you think. Basically if I call `f(a)`, then within

```julia
function f(b)
    ...
end

```

you have `a === b` to start with. That’s all there is to it, really.

---

<div class="post-metadata">

**Author:** ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)\
**Post date:** [September 19, 2020, 7:51am UTC](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897/12 "2020-09-19T07:51:04Z")

</div>

> [@cstjean](#):
>
> `for` loop variables are reused

That would lead me to expect:

```julia
let
  anon = Array{Any}(undef, 2)
  for i = 1:2
    anon[i] = ()-> println(i)
    i += 1
  end

  anon[1]()
  anon[2]()
end
.....
3
3

```

but I need to user `outer` for this to happen:

```julia
let
  anon = Array{Any}(undef, 2)
  i=0
  for outer i = 1:2
    anon[i] = ()-> println(i)
    i += 1
  end

  anon[1]()
  anon[2]()
end
.....
3
3

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 19, 2020, 7:57am UTC](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897/13 "2020-09-19T07:57:21Z")

</div>

The `i += 1` is lowered into `i = i + 1`, which is an assignment, and creates an `i` in the local scope.

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [September 19, 2020, 10:50am UTC](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897/15 "2020-09-19T10:50:41Z")

</div>

This is true, but we have to be honest that in the context of the example it’s still confusing, even with a few reads of the docs.

Knowing that the `i + 1` boxed variable is what will be return by the anonymous function, instead of the value of `i` at the line the function was created on isn’t totally obvious.

And there is an actual practical switch between pass-by-reference and pass-by-value behavior happening in the background when constructing the anonymous function struct, depending on the scope of `i` - so it’s not a completely unrelated problem.

Anyway it’s probably difficult for a newcomer, even with the docs. It’s still confusing to me after registering a bunch of packages. Scoping rules are confusing, Julia has quite a history of demonstrating this.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 19, 2020, 1:47pm UTC](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897/16 "2020-09-19T13:47:00Z")

</div>

> [@Raf](#):
>
> Knowing that the `i + 1` boxed variable is what will be return by the anonymous function, instead of the value of `i` at the line the function was created on isn’t totally obvious.

Possibly. Personally, I don’t expect all aspects of programming to be “totally obvious”. Most interesting things in life aren’t.

Understanding scoping in any nontrivial language requires working through a few examples. Fortunately, the manual has quite a few of these now, but I am sure that more pertinent ones are always welcome as PRs.

> [@Raf](#):
>
> Scoping rules are confusing, Julia has quite a history of demonstrating this.

The _history_ of Julia’s scoping rules is indeed a bit meandering, but that is not really required for understanding how they work _now_. I don’t think that Julia’s scoping rules are especially confusing, but YMMV.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [September 19, 2020, 1:53pm UTC](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897/17 "2020-09-19T13:53:23Z")

</div>

The `i` inside a closure is in the same scope as the `i` outside it so updates to `i` is visible inside the closure. The potentially confusing thing is that a closure can outlive the lexical scope where it was defined.

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [September 19, 2020, 3:29pm UTC](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897/18 "2020-09-19T15:29:51Z")

</div>

Is this what you wanted?

```julia
anon = Array{Any}(undef, 2)
for i = 1:2
  local k = i
  anon[i] = ()-> println(k)
end

```

It gives

```julia
julia> anon[1]()
1

julia> anon[2]()
2

julia>     

```

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [September 19, 2020, 4:18pm UTC](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897/19 "2020-09-19T16:18:43Z")

</div>

In the OP case, as other have already pointed out, I think the root of the problem lies in a very common misunderstanding about the scope of `for` loops.

> A `for` block does not define a single scope, but a succession of scopes one for each iteration.

The distinction between a single scope and a succession of scopes is often little relevant (I believe this is the reason for it being a common misunderstanding). However, together with closures it become relevant and crashes a mental model in which all iterations shared the same inner scope.

I think it can be illustrated by:

```julia
julia> function f()
           for i = 1:5
               if @isdefined x
                   println("x found: $x")
               else
                   println("x not found")
               end
               x = i
           end
           return
       end
f (generic function with 1 method)

julia> f()
x not found
x not found
x not found
x not found
x not found

```

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [September 20, 2020, 10:41pm UTC](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897/20 "2020-09-20T22:41:08Z")

</div>

> [@Henrique\_Becker](#):
>
> In the OP case, as other have already pointed out, I think the root of the problem lies in a very common misunderstanding about the scope of `for` loops.
> 
> > A `for` block does not define a single scope, but a succession of scopes one for each iteration.

While this may be a subtle and common misunderstanding, I don’t think this is the root problem in this case. At least for me it wasn’t.

Both of the following would not meet OP expectation:

Succession of scopes one for each iteration:

```julia
anon = Array{Any}(undef, 2)
for i = 1:2
    anon[i] = ()-> println(i)
    i += 1
end
anon[1]()
anon[2]()

```

Single scope across all iterations:

```julia
anon = Array{Any}(undef, 2)
let
    local i
    for outer i = 1:2
        anon[i] = ()-> println(i)
        i += 1
    end
end
anon[1]()
anon[2]()

```

Rather, I think the key insight to help understanding in this case is:

> [@kristoffer.carlsson](#):
>
> The `i` inside a closure is in the same scope as the `i` outside it so updates to `i` is visible inside the closure. The potentially confusing thing is that a closure can outlive the lexical scope where it was defined.

```julia
anon = Array{Any}(undef, 2)
for i = 1:2
    let i = i
        anon[i] = ()-> println(i)
    end
    i += 1
end
anon[1]()
anon[2]()

```

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [September 20, 2020, 11:32pm UTC](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897/21 "2020-09-20T23:32:53Z")

</div>

Is my solution identical to yours?

---

<div class="post-metadata">

**Author:** ![pauljurczak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pauljurczak/32/921_2.png) [@pauljurczak](https://discourse.julialang.org/u/pauljurczak)\
**Post date:** [September 20, 2020, 11:59pm UTC](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897/22 "2020-09-20T23:59:10Z")

</div>

I wasn’t trying to solve a problem with closures. I was searching for something related to for loop scope and I run into this particular example, which confused me.

This is a part of a bigger problem I have searching through Julia documentation. It would really help to have a BNF (or another formal notation) syntax of Julia published somewhere, otherwise searching for keywords like `outer` is futile.

[Next page](https://discourse.julialang.org/t/i-thought-i-understood-pass-by-sharing-in-julia-until-i-found-this/46897.md?page=2)
