You’re mixing up the types in dispatch and the default element type promotion of array instantiation, which occur separately:
julia> function myappend(x::T, v::Vector{T}) where {T} # dispatch
@info T, typeof(v), typeof(x)
[v..., x] # array instantiation, element type promotion
end
myappend (generic function with 1 method)
julia> myappend(true, Real[1, 2.0])
[ Info: (Real, Vector{Real}, Bool)
3-element Vector{Float64}:
1.0
2.0
1.0
The function call was dispatched to the most fitting (and only) method. The static parameter T
was inferred to be Real
, as you provided v isa Vector{Real}
and true isa Bool <: Real
.
When you instantiated the result vector, you splat the elements of v
and x
, which are 1, 2.0, true
. By default, array instantiation tries to promote numbers to one concrete type; in this case Float64
, so 1
becomes 1.0
, 2.0
stays, true
becomes 1.0
. Note that the promoted type is NOT a supertype of all the original types; Float64
is not a supertype of Int64
or Bool
.
Again, these are two independent events, and method dispatch doesn’t promote types. The automatic promotion in the array instantiation wasn’t necessary either, you could have designated the static parameter as the element type of the array. The elements are unchanged:
julia> function ourappend(x::T, v::Vector{T}) where {T} # dispatch
@info T, typeof(v), typeof(x)
T[v..., x] # array instantiation, no promotion
end
ourappend (generic function with 1 method)
julia> ourappend(true, Real[1, 2.0])
[ Info: (Real, Vector{Real}, Bool)
3-element Vector{Real}:
1
2.0
true