# Type instability of empty \`Array\` with elemental types parameterized by \`UnionAll\`

**URL:** <https://discourse.julialang.org/t/type-instability-of-empty-array-with-elemental-types-parameterized-by-unionall/117618>\
**Category:** General Usage\
**Tags:** type-stability\
**Created:** [July 30, 2024, 2:17am UTC](https://discourse.julialang.org/t/type-instability-of-empty-array-with-elemental-types-parameterized-by-unionall/117618 "2024-07-30T02:17:58Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![frankwswang](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frankwswang/32/18561_2.png) [@frankwswang](https://discourse.julialang.org/u/frankwswang)\
**Post date:** [July 30, 2024, 2:17am UTC](https://discourse.julialang.org/t/type-instability-of-empty-array-with-elemental-types-parameterized-by-unionall/117618/1 "2024-07-30T02:17:58Z")

</div>

MWE:

```julia
julia> v1 = Tuple{AbstractVector{Float64}, Int64}[]
Tuple{AbstractVector{Float64}, Int64}[]

julia> first.(v1)
AbstractVector{Float64}[]

julia> v2 = Tuple{AbstractArray{Float64}, Int64}[]
Tuple{AbstractArray{Float64}, Int64}[]

julia> first.(v2)
Any[]

```

Why can’t `first.(v2)` return `AbstractArray{Float64}[]`?

---

<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:** [July 30, 2024, 5:14am UTC](https://discourse.julialang.org/t/type-instability-of-empty-array-with-elemental-types-parameterized-by-unionall/117618/2 "2024-07-30T05:14:43Z")

</div>

Not sure on the deeper “why”. To expand on your MWE:

```julia
julia> first.(Tuple{AbstractArray{Float64}, Int64}[])
Any[]

julia> first.(Tuple{AbstractArray{Float64}, Int64}[(zeros(1), 1)])
1-element Vector{Vector{Float64}}:
 [0.0]

julia> first.(Tuple{AbstractArray{Float64}, Int64}[(zeros(1), 1), (zeros(2,2), 2)])
2-element Vector{Array{Float64}}:
 [0.0]
 [0.0 0.0; 0.0 0.0]

```

The broadcasting is evidently type unstable, and `@code_warntype` corroborates this by inferring the output as `Vector`.

Thing is, it’s _almost_ doable. `Base.Broadcast.combine_eltypes(first, (v2,))` is how “empty and concretely inferred cases” determine the output array’s element type, and while it returns `Any` as expected, it actually did get to `AbstractArray{Float64}` before `Base.promote_typejoin_union(AbstractArray{Float64})` makes `Any`. But because “ElType is not concrete, [the output array’s element type will] use narrowing” in `Base.Broadcast.copy`, and empty arrays don’t give much to narrow to. I don’t know the reason for this, as people often seem to expect the element type to match the inferred return type of the elementwise operation regardless of how many elements. But it’s customary to do the type “inference” ourselves with preallocation of a manually typed array and in-place broadcasting.
