# Union causes incorrect type parameter extraction?

**URL:** <https://discourse.julialang.org/t/union-causes-incorrect-type-parameter-extraction/65953>\
**Category:** General Usage\
**Created:** [August 6, 2021, 4:34pm UTC](https://discourse.julialang.org/t/union-causes-incorrect-type-parameter-extraction/65953 "2021-08-06T16:34:55Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [August 6, 2021, 4:34pm UTC](https://discourse.julialang.org/t/union-causes-incorrect-type-parameter-extraction/65953/1 "2021-08-06T16:34:55Z")

</div>

```julia
function fun(x::Union{AbstractArray{T}, AbstractArray{Union{T, Missing}}};
            α::T = T(3.0) ) where {T<:AbstractFloat}
    println(typeof(x))
end

julia> fun([1.0, 2.0])
Vector{Float64}

julia> fun([1.0, missing, 2.0])
Vector{Union{Missing, Float64}}

```

on above, everything is fine with only one input belongs to either `AbstractArray{T}` or `AbstractArray{Union{T, Missing}}`.

Now, for a function with **two** those inputs:

```julia
function gun(x::Union{AbstractArray{T}, AbstractArray{Union{T, Missing}}},
            y::Union{AbstractArray{T}, AbstractArray{Union{T, Missing}}};
            α::T = T(3.0) ) where {T<:AbstractFloat}
    println(typeof(x), " ", typeof(y))
end

julia> gun([1.0, 2.0], [3.0, 4.0])
Vector{Float64} Vector{Float64}

julia> gun([1.0, 2.0], [3.0, 4.0, missing])
Vector{Float64} Vector{Union{Missing, Float64}}

julia> gun([1.0, missing, 2.0], [3.0, 4.0, missing])
ERROR: MethodError: no method matching Union{Missing, Float64}(::Float64)
Stacktrace:
 [1] gun(x::Vector{Union{Missing, Float64}}, y::Vector{Union{Missing, Float64}})
   @ Main ./REPL[38]:3
 [2] top-level scope
   @ REPL[43]:1

```

error seems coming from mistaking `Union{Missing, Float64}` as `T`, which should be `Float64`, in the default keyword argument assignment.

noted that if I supply the keyboard argument such that the default value assignment is not called, no error:

```julia
julia> gun([1.0, missing, 2.0], [3.0, 4.0, missing]; α = 1.0)
Vector{Union{Missing, Float64}} Vector{Union{Missing, Float64}}

```

it seems to be **a bug in extracting** the `T` (when `Union` is involved?). using v1.6.1. thanks.

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [August 6, 2021, 5:17pm UTC](https://discourse.julialang.org/t/union-causes-incorrect-type-parameter-extraction/65953/2 "2021-08-06T17:17:01Z")

</div>

I can’t replicate exactly. At least without knowing what `AbF` is.

```julia
julia> function fun_xyz(x::Union{AbstractArray{T}, AbstractArray{<:Union{T, Missing}}},
                        y::Union{AbstractArray{T}, AbstractArray{<:Union{T, Missing}}};
                        α::T = T(3.0) ) where {T<:Real}
           println(typeof(x), " ", typeof(y))
       end
fun_xyz (generic function with 1 method)

julia> fun_xyz([1], [2])
Vector{Int64} Vector{Int64}

julia> fun_xyz([1], [2, missing])
Vector{Int64} Vector{Union{Missing, Int64}}

julia> fun_xyz([1, missing], [2, missing])
Vector{Union{Missing, Int64}} Vector{Union{Missing, Int64}}

```

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [August 7, 2021, 1:48am UTC](https://discourse.julialang.org/t/union-causes-incorrect-type-parameter-extraction/65953/3 "2021-08-07T01:48:07Z")

</div>

oh sorry, `AbF` is `AbstractFloat` in my own abbreviation system:

```julia
julia> AbF
AbstractFloat

```

---

<div class="post-metadata">

**Author:** ![lhnguyen-vn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lhnguyen-vn/32/15449_2.png) [@lhnguyen-vn](https://discourse.julialang.org/u/lhnguyen-vn)\
**Post date:** [August 7, 2021, 6:12am UTC](https://discourse.julialang.org/t/union-causes-incorrect-type-parameter-extraction/65953/4 "2021-08-07T06:12:58Z")

</div>

Determining static parameters with `Union` is generally quite difficult, but it’s worth submitting a bug report in this case since the algorithm is surprisingly not respecting the type constraint.

In the meantime, however, this works:

```julia
julia> foo(x::AbstractArray{<:Union{T,Missing}}, y::AbstractArray{<:Union{T,Missing}}) where {T<:AbstractFloat} = T
foo (generic function with 1 method)

julia> foo([1.], [1.])
Float64

julia> foo([1., missing], [1.])
Float64

julia> foo([1., missing], [1., missing])
Float64

```

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [August 7, 2021, 12:58pm UTC](https://discourse.julialang.org/t/union-causes-incorrect-type-parameter-extraction/65953/5 "2021-08-07T12:58:32Z")

</div>

it works because it does not involve a default value assignment in the keyword argument, which is where the problem occurs

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [August 7, 2021, 12:59pm UTC](https://discourse.julialang.org/t/union-causes-incorrect-type-parameter-extraction/65953/6 "2021-08-07T12:59:10Z")

</div>

i guess u can replicate now?

---

<div class="post-metadata">

**Author:** ![genkuroki](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/genkuroki/32/18030_2.png) [@genkuroki](https://discourse.julialang.org/u/genkuroki)\
**Post date:** [August 7, 2021, 1:13pm UTC](https://discourse.julialang.org/t/union-causes-incorrect-type-parameter-extraction/65953/7 "2021-08-07T13:13:26Z")

</div>

> [@tomtom](#):
>
> using v1.6.1.

I also can’t reproduce it. I’m using Julia v1.6.2. Please upgrade the Julia version.

Code:

```julia
function fun(x::Union{AbstractArray{T}, AbstractArray{Union{T, Missing}}};
            α::T = T(3.0) ) where {T<:AbstractFloat}
    println(typeof(x))
end

function gun(x::Union{AbstractArray{T}, AbstractArray{Union{T, Missing}}},
            y::Union{AbstractArray{T}, AbstractArray{Union{T, Missing}}};
            α::T = T(3.0) ) where {T<:AbstractFloat}
    println(typeof(x), " ", typeof(y))
end

@show VERSION
fun([1.0, 2.0])
fun([1.0, missing, 2.0])
gun([1.0, 2.0], [3.0, 4.0])
gun([1.0, 2.0], [3.0, 4.0, missing])
gun([1.0, missing, 2.0], [3.0, 4.0, missing])
gun([1.0, missing, 2.0], [3.0, 4.0, missing]; α = 1.0)

```

Output (no error):

```julia
VERSION = v"1.6.2"
Vector{Float64}
Vector{Union{Missing, Float64}}
Vector{Float64} Vector{Float64}
Vector{Float64} Vector{Union{Missing, Float64}}
Vector{Union{Missing, Float64}} Vector{Union{Missing, Float64}}
Vector{Union{Missing, Float64}} Vector{Union{Missing, Float64}}

```

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [August 7, 2021, 2:35pm UTC](https://discourse.julialang.org/t/union-causes-incorrect-type-parameter-extraction/65953/8 "2021-08-07T14:35:30Z")

</div>

Strange! the problem persists on my side even updated to v1.6.2 !!!

```julia
julia> @show VERSION
VERSION = v"1.6.2"
v"1.6.2"

julia> gun([1.0, missing, 2.0], [3.0, 4.0, missing])
ERROR: MethodError: no method matching Union{Missing, Float64}(::Float64)
Stacktrace:
 [1] gun(x::Vector{Union{Missing, Float64}}, y::Vector{Union{Missing, Float64}})
   @ Main ./REPL[2]:4
 [2] top-level scope
   @ REPL[7]:1

```

I’m using Mac.

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [August 7, 2021, 2:40pm UTC](https://discourse.julialang.org/t/union-causes-incorrect-type-parameter-extraction/65953/9 "2021-08-07T14:40:12Z")

</div>

> [@lhnguyen-vn](#):
>
> it’s worth submitting a bug report

could u please nicely teach me how to submit a (detailed enough) bug report? Especially in this case seems like some other guys could not replicate the situation…

---

<div class="post-metadata">

**Author:** ![genkuroki](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/genkuroki/32/18030_2.png) [@genkuroki](https://discourse.julialang.org/u/genkuroki)\
**Post date:** [August 7, 2021, 2:51pm UTC](https://discourse.julialang.org/t/union-causes-incorrect-type-parameter-extraction/65953/10 "2021-08-07T14:51:04Z")

</div>

Wow! I’m using Windows. What is going on behind it?

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [August 9, 2021, 6:43am UTC](https://discourse.julialang.org/t/union-causes-incorrect-type-parameter-extraction/65953/11 "2021-08-09T06:43:07Z")

</div>

hello. could u please try to replicate?

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [August 9, 2021, 12:27pm UTC](https://discourse.julialang.org/t/union-causes-incorrect-type-parameter-extraction/65953/12 "2021-08-09T12:27:12Z")

</div>

Yes, I can replicate the error now. I have no idea what’s happening. Please file an issue with the following code

In a fresh session:

```julia
julia> function f1(x::Union{AbstractArray{T}, AbstractArray{Union{T, Missing}}},
                    y::Union{AbstractArray{T}, AbstractArray{Union{T, Missing}}};
                    α::T = T(3.0) ) where {T<:Real}
           println(typeof(x), " ", typeof(y))
       end;

julia> f1([1.0, missing], [2.0, missing])
ERROR: MethodError: no method matching Union{Missing, Float64}(::Float64)
Stacktrace:
 [1] f1(x::Vector{Union{Missing, Float64}}, y::Vector{Union{Missing, Float64}})
   @ Main ./REPL[1]:4
 [2] top-level scope
   @ REPL[2]:1

julia> const AbF = AbstractFloat
AbstractFloat

julia> function f2(x::Union{AbstractArray{T}, AbstractArray{<:Union{T, Missing}}},
                   y::Union{AbstractArray{T}, AbstractArray{<:Union{T, Missing}}};
                   α::T = T(3.0) ) where {T<:AbF}
           println(typeof(x), " ", typeof(y))
       end;

julia> f2([1.0, missing], [2.0, missing])
Vector{Union{Missing, Float64}} Vector{Union{Missing, Float64}}

```

Also in a fresh session

```julia
julia> const AbF = AbstractFloat
AbstractFloat

julia> function f2(x::Union{AbstractArray{T}, AbstractArray{<:Union{T, Missing}}},
                   y::Union{AbstractArray{T}, AbstractArray{<:Union{T, Missing}}};
                   α::T = T(3.0) ) where {T<:AbF}
           println(typeof(x), " ", typeof(y))
       end;

julia> f2([1.0, missing], [2.0, missing])
Vector{Union{Missing, Float64}} Vector{Union{Missing, Float64}}

```

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [August 9, 2021, 3:00pm UTC](https://discourse.julialang.org/t/union-causes-incorrect-type-parameter-extraction/65953/13 "2021-08-09T15:00:45Z")

</div>

[issue submitted here](https://github.com/JuliaLang/julia/issues/41841). Thanks.

---

<div class="post-metadata">

**Author:** ![jameson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jameson/32/23_2.png) [@jameson](https://discourse.julialang.org/u/jameson)\
**Post date:** [August 9, 2021, 4:08pm UTC](https://discourse.julialang.org/t/union-causes-incorrect-type-parameter-extraction/65953/14 "2021-08-09T16:08:12Z")

</div>

It sounds like you are attempting to make this parametric in the wrong place, so your constraints don’t work. I think this version will work:

```julia
function fun(x::AbstractArray{T}; α=3.0) where {T<:Union{AbstractFloat,Missing}}
    T = nonmissingtype(T)
    α = T(α)
...

```

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [August 10, 2021, 3:17am UTC](https://discourse.julialang.org/t/union-causes-incorrect-type-parameter-extraction/65953/15 "2021-08-10T03:17:48Z")

</div>

yes it “works”:

```julia
julia> function fun1(x::AbstractArray{T};
                       α=3.0) where {T<:Union{AbstractFloat,Missing}}
           T1 = nonmissingtype(T)
           α = T1(α)
           println(typeof(x))
       end
fun1 (generic function with 1 method)

julia> function fun2(x::AbstractArray{T},
                       y::AbstractArray{T};
                       α=3.0) where {T<:Union{AbstractFloat,Missing}}
           T1 = nonmissingtype(T)
           α = T1(α)
           println(typeof(x), " ", typeof(y))
       end
fun2 (generic function with 1 method)

julia> fun1([2.0, missing])
Vector{Union{Missing, Float64}}

julia> fun2([2.0, missing], [3.0, missing])
Vector{Union{Missing, Float64}} Vector{Union{Missing, Float64}}

```

but it’s a bit weird:

1. we need another **variable** `T1`, rather than the type parameter, to capture a `Float64`
2. the type of `α` may change, i.e. unstable type

so… seems like it’s a strange solution… but maybe it’s the way to help type inference as the original problem requires some “AI inference” that is very difficult to implement…

---

<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:** [August 10, 2021, 6:51am UTC](https://discourse.julialang.org/t/union-causes-incorrect-type-parameter-extraction/65953/16 "2021-08-10T06:51:44Z")

</div>

> [@tomtom](#):
>
> the type of `α` may change, i.e. unstable type

Maybe I’m missing something here, but this is never type unstable. If it’s a `Union{T, Missing}`, it will always be `T`. If it’s just a `T`, it’s always a `T`. The difference is known at compile time, because the eltype of the vector is known at compile time, thus the compiler knows about it and at least two methods will be compiled, making it type stable.
