Dispatch surprise with vectors

I’ve been trying to implement some functions taking advantage of some default values as well as multiple dispatch and I stumbled upon the following behavior. It is surprising to me but maybe it is just the way things work in julia.

# Define a default const
const defn = [1,2,3]
# Define a function taking an abstract vector as argument and that returns it
fun1(numbers = defn::AbstractVector{<:Number}) = numbers

As expected calling fun1() returns

julia> fun1()
3-element Vector{Int64}:
 1
 2
 3

and fun1([1,2,5])

julia> fun1([1,2,5])
3-element Vector{Int64}:
 1
 2
 5

But the big surprise (to me at least) is that calling fun1(10) also works and returns

julia> fun1(10)
10

while 10 isa AbstractVector gives

julia> 10 isa AbstractVector{<:Number}
false

Could anyone explain how this works, I would have expected a dispatch error saying that fun1(::Int64) does not exist. As a sidenote, this is exactly what happens if fun1 has no default value…

Both of these are valid but have different meaning:

fun1(x::AbstractVector{<:Number}=[1,2,3]) = x
fun2(x=[1,2,3]::AbstractVector{<:Number}) = x

You probably aimed for the former. The latter asserts that [1, 2, 3] (not the argument x) is an AbstractVector{<:Number}.

7 Likes

Well, needless to say that I completely overlooked that slight yet important difference, thanks for the help !