# Strange outcome for the Julia list with different type of elements

**URL:** <https://discourse.julialang.org/t/strange-outcome-for-the-julia-list-with-different-type-of-elements/125409>\
**Category:** New to Julia\
**Tags:** julia\
**Created:** [January 30, 2025, 10:14pm UTC](https://discourse.julialang.org/t/strange-outcome-for-the-julia-list-with-different-type-of-elements/125409 "2025-01-30T22:14:05Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![miniskar](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/miniskar/32/210144_2.png) [@miniskar](https://discourse.julialang.org/u/miniskar)\
**Post date:** [January 30, 2025, 10:14pm UTC](https://discourse.julialang.org/t/strange-outcome-for-the-julia-list-with-different-type-of-elements/125409/1 "2025-01-30T22:14:05Z")

</div>

Here is the minimum working example.

```julia
julia> f= rand(Float32, 8)
8-element Vector{Float32}:
 0.31442094
 0.31442094
 0.2593087
 0.2593087
 0.11091578
 0.11091578
 0.14340413
 0.14340413

julia> i = rand(Int32, 8)
8-element Vector{Int32}:
 -1010112671
   346170778
   668418952
   -50293529
  1151894370
   208560393
 -1186865689
 -1973369622

julia> v_fi = [f, i]
2-element Vector{Vector{Float32}}:
 [0.31442094, 0.31442094, 0.2593087, 0.2593087, 0.11091578, 0.11091578, 0.14340413, 0.14340413]
 [-1.01011264f9, 3.4617078f8, 6.6841894f8, -5.029353f7, 1.1518944f9, 2.085604f8, -1.1868657f9, -1.9733696f9]

julia> any_v_fi = Any[f, i]
2-element Vector{Any}:
 Float32[0.31442094, 0.31442094, 0.2593087, 0.2593087, 0.11091578, 0.11091578, 0.14340413, 0.14340413]
 Int32[-1010112671, 346170778, 668418952, -50293529, 1151894370, 208560393, -1186865689, -1973369622]

julia> scalar_v_fi = [20, f, i]
3-element Vector{Any}:
 20
   Float32[0.31442094, 0.31442094, 0.2593087, 0.2593087, 0.11091578, 0.11091578, 0.14340413, 0.14340413]
   Int32[-1010112671, 346170778, 668418952, -50293529, 1151894370, 208560393, -1186865689, -1973369622]

```

In the above example, I am expecting Julia to preserve the data type of `f` and `i` in the `v_fi` same like `any_v_fi`. It should have used “Any” by default to the list for `v_fi`. Surprisingly, it applies “Any” to `scalar_v_fi` when there is one scalar element in the list. This behavior is not consistent.

---

<div class="post-metadata">

**Author:** ![danielwe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielwe/32/35657_2.png) [@danielwe](https://discourse.julialang.org/u/danielwe)\
**Post date:** [January 30, 2025, 10:46pm UTC](https://discourse.julialang.org/t/strange-outcome-for-the-julia-list-with-different-type-of-elements/125409/2 "2025-01-30T22:46:25Z")

</div>

The element type of an array `[a, b, c]` is computed by the function `promote_type(typeof(a), typeof(b), typeof(c))`. What you’re observing is the following:

```julia-repl
julia> promote_type(Vector{Int32}, Vector{Float32})
Vector{Float32} (alias for Array{Float32, 1})

julia> promote_type(Int, Vector{Int32}, Vector{Float32})
Any

```

That is, in `v_fi`, when you mix a `Vector{Int32}` and a `Vector{Float32}`, the promoted type is `Vector{Float32}`, and instances of `Vector{Int32}` are converted accordingly. In `scalar_v_fi` you’re also adding an `Int` into the mix, and now `promote_type` falls back to `Any`, hence no element is converted.

People may argue whether this behavior is desirable, but it is deliberate.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 31, 2025, 1:40am UTC](https://discourse.julialang.org/t/strange-outcome-for-the-julia-list-with-different-type-of-elements/125409/3 "2025-01-31T01:40:34Z")

</div>

Basically, homogeneous containers (analogous to numpy arrays) are much faster than heterogeneous containers, so Julia usually prefers to promote to a common type if possible (it’s not possible if one element is a scalar and another is a vector).

But of course you can opt out if you specifically want `Vector{Any}` (the analogue of a Python `list`).

---

<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:** [January 31, 2025, 11:33am UTC](https://discourse.julialang.org/t/strange-outcome-for-the-julia-list-with-different-type-of-elements/125409/4 "2025-01-31T11:33:35Z")

</div>

In many cases where you need to lump together things of different data type, like in a python list, a tuple is usually better in julia. It’s immutable, so you can’t change it, though you can change mutable elements inside it.

```julia
julia> f = rand(Float32, 10);
julia> i = rand(Int32, 10);
julia> fi = (f, i)
(Float32[0.3967855, 0.74455744, 0.14703006, 0.44867855, 0.48266786, 0.91201013, 0.28800505, 0.5439985, 0.06666976, 0.710635], Int32[-15829316, 604588000, 810921946, 929331054, 1339835954, -911415111, 142170320, 350952455, 327657902, -1265631069])

```

or a named tuple:

```julia
julia> nfi = (f=f, i=i);
julia> nfi.f
10-element Vector{Float32}:
...
julia> nfi.i
10-element Vector{Int32}:
...
julia> nfi.i[4] = 42
42

```

---

<div class="post-metadata">

**Author:** ![miniskar](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/miniskar/32/210144_2.png) [@miniskar](https://discourse.julialang.org/u/miniskar)\
**Post date:** [February 2, 2025, 3:43am UTC](https://discourse.julialang.org/t/strange-outcome-for-the-julia-list-with-different-type-of-elements/125409/5 "2025-02-02T03:43:25Z")

</div>

Thank you all for the replies and discussion. I agree that there are workarounds and alternatives to lump together different data types of elements either using tuple or Any. However, it will be simple if we preserve the type of elements by default if anyone uses Julia list even without Any. It will make it easy with simplified understanding of using Julia list. If we need the functionality of promote\_type to all elements of list, a new function or keyword can be provided on list like promote.

---

<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:** [February 2, 2025, 5:29am UTC](https://discourse.julialang.org/t/strange-outcome-for-the-julia-list-with-different-type-of-elements/125409/6 "2025-02-02T05:29:27Z")

</div>

> [@miniskar](#):
>
> However, it will be simple if we preserve the type of elements by default if anyone uses Julia list

Respectfully, I disagree. Automatically attempted promotion in the absence of an explicit element type in array literals has been the standard for a long time, especially used on subtypes of `Number` for improved performance:

```julia
julia> [1 2//3 4.5 6im]
1×4 Matrix{ComplexF64}:
 1.0+0.0im 0.666667+0.0im 4.5+0.0im 0.0+6.0im

```

Removing automatic promotion would not only be breaking, it would require more typing in more common situations than typing a short `Any` in much rarer situations. Manually calling a promotion function would not be a good solution because you need to instantiate an unwanted `Any` array as an input. A new keyword would not be a good solution because it complicates array literal syntax; you can’t just put it in front of the brackets because that already designates the element type.

Your misuse of the word “list” for `Array`s suggests your preference for no automatic promotion comes from a different programming language (we can’t assume it’s the one people have already mentioned). Of course it’d be easier for you to understand if Julia syntax behaved more like a language you’re used to, but it’s impossible for any one language to be similar to every language any user might come from. We have to adapt to different syntax and styles when going between languages, and Julia is no exception.
