# Different modification behavior when looping over array of variables of different array types

**URL:** <https://discourse.julialang.org/t/different-modification-behavior-when-looping-over-array-of-variables-of-different-array-types/132243>\
**Category:** General Usage\
**Tags:** question, for-loop\
**Created:** [September 10, 2025, 12:39am UTC](https://discourse.julialang.org/t/different-modification-behavior-when-looping-over-array-of-variables-of-different-array-types/132243 "2025-09-10T00:39:47Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![chaseleslie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chaseleslie/32/22188_2.png) [@chaseleslie](https://discourse.julialang.org/u/chaseleslie)\
**Post date:** [September 10, 2025, 12:39am UTC](https://discourse.julialang.org/t/different-modification-behavior-when-looping-over-array-of-variables-of-different-array-types/132243/1 "2025-09-10T00:39:47Z")

</div>

Example code:

```julia
function filterarrays!(d)
    for arr in [d["a"], d["b"]]
        deleteat!(arr, 2)
    end
end

d = Dict("a" => [1, 2, 3], "b" => [1., 2., 3.])
display(d)
filterarrays!(d)
display(d)

```

With output:

```julia
Dict{String, Vector} with 2 entries:
  "b" => [1.0, 2.0, 3.0]
  "a" => [1, 2, 3]
Dict{String, Vector} with 2 entries:
  "b" => [1.0, 3.0]
  "a" => [1, 2, 3]

```

In the case of the `b` key of dictionary `d`, the middle array element is removed as expected. For the values of the `a` key, no elements are removed. I’m not sure if the reason for the difference is related to [this topic](https://discourse.julialang.org/t/placing-variables-in-array-makes-a-copy-of-the-variables/69397), but in the example above the two arrays have different types and the output for the Float64 array (`b`) is as I would expect.

Can anyone explain why the loop behavior is different here?

(Julia Version 1.11.6)

---

<div class="post-metadata">

**Author:** ![StevenSiew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevensiew/32/218393_2.png) [@StevenSiew](https://discourse.julialang.org/u/StevenSiew)\
**Post date:** [September 10, 2025, 1:03am UTC](https://discourse.julialang.org/t/different-modification-behavior-when-looping-over-array-of-variables-of-different-array-types/132243/2 "2025-09-10T01:03:50Z")

</div>

> [@chaseleslie](#):
>
> ```julia-auto
> function filterarrays!(d)
> for arr in [d["a"], d["b"]]
> deleteat!(arr, 2)
> end
> end
> 
> d = Dict("a" => [1, 2, 3], "b" => [1., 2., 3.])
> display(d)
> filterarrays!(d)
> display(d)
> 
> ```

```julia
julia> d = Dict("a" => [1, 2, 3], "b" => [1., 2., 3.])
Dict{String, Vector} with 2 entries:
  "b" => [1.0, 2.0, 3.0]
  "a" => [1, 2, 3]

julia> function filterarrays!(d)
           for arr in Any[d["b"], d["a"]]
               deleteat!(arr, 2) |> display
           end
       end
filterarrays! (generic function with 1 method)

julia> display(d)
Dict{String, Vector} with 2 entries:
  "b" => [1.0, 2.0, 3.0]
  "a" => [1, 2, 3]

julia> filterarrays!(d)
2-element Vector{Float64}:
 1.0
 3.0
2-element Vector{Int64}:
 1
 3

julia> display(d)
Dict{String, Vector} with 2 entries:
  "b" => [1.0, 3.0]
  "a" => [1, 3]

```

you just use “Any” before [d[“a”] , d[“b”] ]

---

<div class="post-metadata">

**Author:** ![chaseleslie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chaseleslie/32/22188_2.png) [@chaseleslie](https://discourse.julialang.org/u/chaseleslie)\
**Post date:** [September 10, 2025, 1:19am UTC](https://discourse.julialang.org/t/different-modification-behavior-when-looping-over-array-of-variables-of-different-array-types/132243/3 "2025-09-10T01:19:47Z")

</div>

Thanks, that is producing the output I expected. When not using Any, does Julia change the Int64 to Float64 so they have common type?

---

<div class="post-metadata">

**Author:** ![StevenSiew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevensiew/32/218393_2.png) [@StevenSiew](https://discourse.julialang.org/u/StevenSiew)\
**Post date:** [September 10, 2025, 4:54am UTC](https://discourse.julialang.org/t/different-modification-behavior-when-looping-over-array-of-variables-of-different-array-types/132243/4 "2025-09-10T04:54:32Z")

</div>

```julia
julia> d = Dict("a" => [1, 2, 3], "b" => [1., 2., 3.])
Dict{String, Vector} with 2 entries:
  "b" => [1.0, 2.0, 3.0]
  "a" => [1, 2, 3]

julia> result1 = [d["b"], d["a"]]
2-element Vector{Vector{Float64}}:
 [1.0, 2.0, 3.0]
 [1.0, 2.0, 3.0]

julia> result2 = Any[d["b"], d["a"]]
2-element Vector{Any}:
 [1.0, 2.0, 3.0]
 [1, 2, 3]

```

---

<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:** [September 10, 2025, 7:14am UTC](https://discourse.julialang.org/t/different-modification-behavior-when-looping-over-array-of-variables-of-different-array-types/132243/5 "2025-09-10T07:14:43Z")

</div>

Note that you could alternatively use a `Tuple`, which also saves you an allocation:

```julia
function filterarrays!(d)
    for arr in (d["a"], d["b"]) # <-- tuple here
        deleteat!(arr, 2)
    end
end

d = Dict("a" => [1, 2, 3], "b" => [1., 2., 3.])
filterarrays!(d)
display(d)
# Dict{String, Vector} with 2 entries:
# "b" => [1.0, 3.0]
# "a" => [1, 3]
```

---

<div class="post-metadata">

**Author:** ![affans](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/affans/32/11911_2.png) [@affans](https://discourse.julialang.org/u/affans)\
**Post date:** [September 10, 2025, 4:14pm UTC](https://discourse.julialang.org/t/different-modification-behavior-when-looping-over-array-of-variables-of-different-array-types/132243/6 "2025-09-10T16:14:25Z")

</div>

This seems like a bug to me. Is the statement `[d["b"], d["a"]]` making a copy of `d["a"]` with elements promoted to `Float64` and leaving `d["b"]` as a reference to to the original array?

---

<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:** [September 10, 2025, 4:37pm UTC](https://discourse.julialang.org/t/different-modification-behavior-when-looping-over-array-of-variables-of-different-array-types/132243/7 "2025-09-10T16:37:03Z")

</div>

> [@affans](#):
>
> This seems like a bug to me.

Well, it is [documented](https://docs.julialang.org/en/v1/manual/arrays/#man-array-literals):

> Arrays can also be directly constructed with square braces; the syntax `[A, B, C, ...]` creates a one-dimensional array (i.e., a vector) containing the comma-separated arguments as its elements. The element type ([`eltype`](https://docs.julialang.org/en/v1/base/collections/#Base.eltype)) of the resulting array is automatically determined by the types of the arguments inside the braces. If all the arguments are the same type, then that is its `eltype`. _If they all have a common [promotion type](https://docs.julialang.org/en/v1/manual/conversion-and-promotion/#conversion-and-promotion) then they get converted to that type using [`convert`](https://docs.julialang.org/en/v1/base/base/#Base.convert) and that type is the array’s `eltype`._ Otherwise, a heterogeneous array that can hold anything — a `Vector{Any}` — is constructed; this includes the literal `[]` where no arguments are given. [Array literal can be typed](https://docs.julialang.org/en/v1/manual/arrays/#man-array-typed-literal) with the syntax `T[A, B, C, ...]` where `T` is a type.

(_emphasis_ mine),

```julia-repl
help?> convert
search: convert Base.cconvert const collect

  convert(T, x)

(...)

If T is a collection type and x a collection, the result of convert(T, x) may alias all or part of x.

  julia> x = Int[1, 2, 3];

  julia> y = convert(Vector{Int}, x);

  julia> y === x
  true

```

---

<div class="post-metadata">

**Author:** ![affans](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/affans/32/11911_2.png) [@affans](https://discourse.julialang.org/u/affans)\
**Post date:** [September 10, 2025, 4:42pm UTC](https://discourse.julialang.org/t/different-modification-behavior-when-looping-over-array-of-variables-of-different-array-types/132243/8 "2025-09-10T16:42:11Z")

</div>

I think the conversion to `Float64` is okay (and documented like you mention), but it does not seem correct that a copy is made for `d["a"]` with eltype `Float64` while a reference is maintained to the `d["b"]`. Maybe it is correct behaviour.

---

<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:** [September 10, 2025, 4:57pm UTC](https://discourse.julialang.org/t/different-modification-behavior-when-looping-over-array-of-variables-of-different-array-types/132243/9 "2025-09-10T16:57:41Z")

</div>

I agree it can lead to unintuitive behaviour as in this thread, but it is the logical consequence of the requirements that

1. You want to promote to a common type (ultimately via `convert`) in array literals
2. You want `convert(typeof(x), x) === x`.

You might disagree with these requirements (though 2 seems pretty essential), but they are certainly intentional design choices. So yeah, I’d say this is correct behaviour.
