# Assigning to a view of an array

**URL:** <https://discourse.julialang.org/t/assigning-to-a-view-of-an-array/132869>\
**Category:** New to Julia\
**Tags:** arrays, views\
**Created:** [October 3, 2025, 10:27pm UTC](https://discourse.julialang.org/t/assigning-to-a-view-of-an-array/132869 "2025-10-03T22:27:01Z")\
**Posts on this page:** 18\
**Page:** 2

<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:** [October 5, 2025, 5:33am UTC](https://discourse.julialang.org/t/assigning-to-a-view-of-an-array/132869/21 "2025-10-05T05:33:11Z")

</div>

> [@WalterMadelim](#):
>
> I feel somewhat strange to add a `$` at the left-hand-side of a `=`.

This is only for benchmarking, you don’t use `$` in your running code.

The time measurements are statistical samples, and subject to noise. Use `@benchmark` instead of `@btime` for a fuller picture.

---

<div class="post-metadata">

**Author:** ![eldee](https://avatars.discourse-cdn.com/v4/letter/e/b5a626/32.png) [@eldee](https://discourse.julialang.org/u/eldee)\
**Post date:** [October 5, 2025, 8:18am UTC](https://discourse.julialang.org/t/assigning-to-a-view-of-an-array/132869/22 "2025-10-05T08:18:11Z")

</div>

> [@WalterMadelim](#):
>
> I feel somewhat strange to add a `$` at the left-hand-side of a `=`.

You don’t have to use `$` to get an accurate benchmark, you just have to avoid (untyped) global variables. Putting everything into a function is also fine:

```julia-repl
julia> import Random.seed! as seed!

julia> function test_foreach(a)
           foreach(i -> setindex!(a, rand(), i), eachindex(a));
       end

julia> function test()
           N = 9999

           seed!(1)
           a = -rand(N, N)
           seed!(2)
           @time @. a = rand()

           seed!(1)
           a = -rand(N, N)
           seed!(2)
           @time broadcast!(_ -> rand(), a, a)

           seed!(1)
           a = -rand(N, N)
           seed!(2)
           @time foreach(i -> setindex!(a, rand(), i), eachindex(a)) # issues with closure?

           seed!(1)
           a = -rand(N, N)
           seed!(2)
           @time test_foreach(a)
       end;

julia> test() # second run
  0.117221 seconds
  0.111353 seconds
  4.698482 seconds (199.96 M allocations: 2.980 GiB, 8.26% gc time)
  0.112201 seconds

```

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [October 5, 2025, 10:15am UTC](https://discourse.julialang.org/t/assigning-to-a-view-of-an-array/132869/23 "2025-10-05T10:15:40Z")

</div>

> [@eldee](#):
>
> ```julia-auto
> a = -rand(N, N)
> seed!(2)
> @time foreach(i -> setindex!(a, rand(), i), eachindex(a)) # issues with closure?
> 
> ```

Here a function `i -> setindex!(a, ...)` is created.  
The `a` is a name of a matrix, which is from the outer layer.  
But the `a` is _not written to_. Why is this a closure?

---

<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:** [October 5, 2025, 10:56am UTC](https://discourse.julialang.org/t/assigning-to-a-view-of-an-array/132869/24 "2025-10-05T10:56:01Z")

</div>

> [@WalterMadelim](#):
>
> But the `a` is _not written to_.

What do you mean by this? `a` is written to by `setindex!`

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [October 5, 2025, 11:19am UTC](https://discourse.julialang.org/t/assigning-to-a-view-of-an-array/132869/25 "2025-10-05T11:19:25Z")

</div>

`a` is mutated by `setindex!`, but is not re-bound to another object via `a = somethingElse`.  
The latter leads to a Red `Core.Box`.

```julia
function no_written_to()
    a = [1]
    () -> setindex!(a, 2)
end
@code_warntype no_written_to() # a::Vector{Int64}

function has_rebind()
    a = [1]
    () -> setindex!(a+=1, 2)
end
@code_warntype has_rebind() # a::Core.Box

```

---

<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:** [October 5, 2025, 11:30am UTC](https://discourse.julialang.org/t/assigning-to-a-view-of-an-array/132869/26 "2025-10-05T11:30:07Z")

</div>

> [@WalterMadelim](#):
>
> `a+=1`

This is not a legal operation for arrays anyway:

```julia
julia> has_rebind()()
ERROR: MethodError: no method matching +(::Vector{Int64}, ::Int64)
For element-wise addition, use broadcasting with dot syntax: array .+ scalar
The function `+` exists, but no method is defined for this combination of argument types.

```

But even if you fix this:

```julia-auto
function has_rebind()
    a = [1]
    () -> setindex!(a+=[1], 2)
end

```

I don’t really see what you are getting at. The above code is equivalent to

```julia-auto
function has_rebind()
    a = [1]
    b = a + [1]
    () -> setindex!(b, 2)
end

```

Edit: It seems that the compiler is better able to infer types for the latter than the former version, but semantically they are the same. Hmm, or so I _think_, but closures are weird. Maybe the addition happens later..

---

<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:** [October 5, 2025, 11:44am UTC](https://discourse.julialang.org/t/assigning-to-a-view-of-an-array/132869/27 "2025-10-05T11:44:11Z")

</div>

I think perhaps this is a better parallel:

```julia-auto
function has_rebind2()
    a = [1]
    () -> setindex!((b = a + [1]; b), 2)
end

```

`a` is not rebound, a new array, `b`, is allocated and returned when calling `has_rebind2()()`, while `a` remains unaffected.

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [October 5, 2025, 11:47am UTC](https://discourse.julialang.org/t/assigning-to-a-view-of-an-array/132869/28 "2025-10-05T11:47:34Z")

</div>

> [@DNF](#):
>
> I don’t really see what you are getting at. The above code is equivalent to
> 
> ```julia-auto
> function has_rebind()
> a = [1]
> b = a + [1]
> () -> setindex!(b, 2)
> end
> 
> ```

No. I think the equivalent reformulations are

```julia
function has_rebind()
    a = [1]
    () -> setindex!(a+=[1], 2)
end
function has_rebind()
    a = [1]
    function()
        setindex!(a+=[1], 2)
    end
end
function has_rebind()
    a = [1]
    function()
        a = a + [1]
        setindex!(a, 2)
    end
end
@code_warntype has_rebind() # a::Core.Box

# cf. this
function not_has_rebind()
    a = [1]
    function()
        a
        setindex!(a, 2)
    end
end
@code_warntype not_has_rebind() # a::Vector{Int}

```

* * *

Wait a minute, julia is AGAIN challenging my brain:  
Why do the following code has `Core.Box`???

```julia
function very_strange()
    a = [1]
    a = a + [1]
    () -> f(a)
end
@code_warntype very_strange() # a@_3::Core.Box, a@_4::Union{}

```

---

<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:** [October 5, 2025, 11:56am UTC](https://discourse.julialang.org/t/assigning-to-a-view-of-an-array/132869/29 "2025-10-05T11:56:38Z")

</div>

I’m not really getting your point, though. There is no re-binding happening in the `has_rebind` function. I think my latest re-formulation is the correct one:

> [@DNF](#):
>
> ```julia-auto
> function has_rebind2()
> a = [1]
> () -> setindex!((b = a + [1]; b), 2)
> end
> 
> ```

---

<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:** [October 5, 2025, 11:57am UTC](https://discourse.julialang.org/t/assigning-to-a-view-of-an-array/132869/30 "2025-10-05T11:57:55Z")

</div>

> [@WalterMadelim](#):
>
> `() -> f(a)`

What is `f`?

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [October 5, 2025, 12:06pm UTC](https://discourse.julialang.org/t/assigning-to-a-view-of-an-array/132869/31 "2025-10-05T12:06:57Z")

</div>

This is inconsequential. Because `a` is an input arg to `f`.  
What `f` will do on `a`? This is irrelevant, because in the body of `f`, `a` will become another local variable within the body of `f`.

* * *

Purely from the standpoint of observing its appearance, There was **only one** `a` in `very_strange`. I cannot figure out why there are two, and even one being `Core.Box`. Inconceivable for me.

* * *

A concise conclusion:

```julia
function no_Core_Box()
    a = 1
    () -> f(a)
end
function has_Core_Box() # this is strange
    a = 1
    a = 1
    () -> f(a)
end
function has_Core_Box() # this is clear
    a = 1
    function()
        a = 2
    end
end

```

This pair is also strange

```julia
function no_Core_Box()
    local a
    for j = 1:2
        a = 1j
        Threads.@spawn f(a)
    end
end
function has_Core_Box()
    a = 1
    a = 2
    Threads.@spawn f(a)
end

```

* * *

Compare the head line of `function`, `let`, `for`:

```julia
julia> function can_run(a::Bool) # can be defined 
           println(typeof(a))
           a::Int = a
       end
can_run (generic function with 1 method)

julia> can_run(true) # and can run
Bool
true

julia> function no_define() # cannot be defined
           for a::Bool = true
               a ::Int = a
           end
       end
ERROR: syntax: multiple type declarations for "a"
Stacktrace:
 [1] top-level scope
   @ REPL[3]:1

julia> function no_define() # cannot be defined
           let a::Bool = true
               a::Int = a
           end
       end
ERROR: syntax: multiple type declarations for "a"
Stacktrace:
 [1] top-level scope
   @ REPL[4]:1

```

---

<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:** [October 5, 2025, 2:23pm UTC](https://discourse.julialang.org/t/assigning-to-a-view-of-an-array/132869/32 "2025-10-05T14:23:02Z")

</div>

It seems I have never really understood the behaviour of closures, and it seems that they in fact capture bindings, not values (contrary to my intuition, and apparently contrary to the much repeated claim that variables are “just labels”, so that mutability as a concept should not apply.)

Since closures capture variables/bindings and not values, there is a difference in how the compiler is able to optimize `no_Core_Box` vs `has_Core_Box`. With a single assignment, the compiler assumes that `a = 1` is immutable, while multiple assignment confuses it. In principle, the compiler could figure out that the functions are identical, but it’s just not smart enough.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [October 5, 2025, 2:35pm UTC](https://discourse.julialang.org/t/assigning-to-a-view-of-an-array/132869/33 "2025-10-05T14:35:38Z")

</div>

> [@WalterMadelim](#):
>
> I cannot figure out why there are two, and even one being `Core.Box`. Inconceivable for me.

A breadcrumb (or rather, a whole bread) for you: [performance of captured variables in closures · Issue #15276 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/15276)

In essence, closure capturing is done purely on a syntactic level at the moment (during lowering to be precise), long before anything related to type inference runs. So at the point when type inference runs, it already sees an actual call to `Core.Box` (inserted by lowering), and at that point it’s indistinguishable from a user-written `Core.Box`. This is very conservative, so any dual assignment of a captured variable defaults to boxing, causing an allocation, tanking performance, and causing all kinds of unintuitive behavior.

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [October 6, 2025, 9:09am UTC](https://discourse.julialang.org/t/assigning-to-a-view-of-an-array/132869/34 "2025-10-06T09:09:09Z")

</div>

I probably will not have the ability to read that topic (it’s somewhat long).

But I guess one of the most annoying fact is that it destroys my intuition.

Normally if I write the code `a = 789`, then julia is doing “bind the label `a` to the object `789`”.  
So at any instant, `a` is either bound to some old object, or `a` is bound to a new object. In other words, there is no intermediate states. Or, It is 2-point discrete \{0, 1\}, not the continuous interval [0, 1].

But if `a` becomes a `Core.Box` inadvertently, I still write the code `a = 789` from my viewpoint. But Now julia is doing mutation like

```julia
%4 = a::Core.Box
Core.setfield!(%4, :contents, 789)

```

i.e. Now it has a continuous possibility to be anything between the interval [0, 1]. This is annoying.

* * *

Edit: So I want to ask:

- is there any methods to detect that inadvertent `Core.Box` happens during my runtime?

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [October 6, 2025, 10:31am UTC](https://discourse.julialang.org/t/assigning-to-a-view-of-an-array/132869/35 "2025-10-06T10:31:11Z")

</div>

> [@DNF](#):
>
> it seems that they in fact capture bindings, not values (contrary to my intuition, and apparently contrary to the much repeated claim that variables are “just labels”, so that mutability as a concept should not apply.)

Mutability in Julia indeed does not apply to variables because it’s a property of types and their values. Non-`const` variables are _reassignable_, and that might be called mutability in _other languages_ where variables are named values. Same word in different contexts has different meanings.

---

<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:** [October 6, 2025, 10:48am UTC](https://discourse.julialang.org/t/assigning-to-a-view-of-an-array/132869/36 "2025-10-06T10:48:14Z")

</div>

> [@WalterMadelim](#):
>
> is there any methods to detect that inadvertent `Core.Box` happens during my runtime?

Aren’t you detecting this with `@code_warntype` etc? What sort of alternative mechanism are you looking for, a linter, for example? If so, perhaps Cthulhu.jl with editor integration might be what you want.

---

<div class="post-metadata">

**Author:** ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)\
**Post date:** [October 6, 2025, 11:01am UTC](https://discourse.julialang.org/t/assigning-to-a-view-of-an-array/132869/37 "2025-10-06T11:01:05Z")

</div>

Some times the critical part I want to look into is at some deeper level of function calling (which entails parameters that is not easy to give by hand (they were give by program when running)), e.g.

```julia
function main()
    ...
end
function shell()
    main()
end
@code_warntype shell() # don't look into main()

```

Anyway, thanks.

---

<div class="post-metadata">

**Author:** ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)\
**Post date:** [October 6, 2025, 11:55am UTC](https://discourse.julialang.org/t/assigning-to-a-view-of-an-array/132869/38 "2025-10-06T11:55:24Z")

</div>

Both Cthulhu.jl and JET.jl can do type stability checks deeper than `@code_warntype`.

[Previous page](https://discourse.julialang.org/t/assigning-to-a-view-of-an-array/132869.md?page=1)
