# Method dispatch for tuples

#1

I have the following definitions:

``````f(x::Tuple{Any, Any}) = "Tuple{Any, Any}"
f(x::NTuple{N}) where N = "NTuple{N}"
``````

When I write `f((1,2))` the call satisfies both definitions. On Julia 0.6 the second definition is called but I do not understand why. Is this a bug or there is some explanation for this behavior?

I would assume that `MethodError` should be thrown as this call is ambiguous because:

``````julia> typeof((1,2)) <: Tuple{Any, Any}
true

julia> typeof((1,2)) <: NTuple{N} where N
true
``````

but

``````julia> Tuple{Any, Any} <: NTuple{N} where N
false

julia> (NTuple{N} where N) <: Tuple{Any, Any}
false
``````

#2

`NTuple` requires that all the inputs have the same type, so

``````julia> typeof((1,2)) <: NTuple{N} where N
true

julia> typeof((1,2.0)) <: NTuple{N} where N
false
``````

Hence it is deemed “more specific,” as the lingo goes, and hence gets priority.

Of course this can be debated: why should the element type receive priority over the length? If you need to have manual control over this, you can always define a method for `::NTuple{2}` and have it do whichever one you want.

#3

Thank you. Now I understand that it is governed by `jl_type_morespecific`.

As a side observation: for `Array` dimension gets the priority over element type as `Array{T, 1} where T` is more specific than `Array{Int, N} where N` (so I would say it is the other way around than in `Tuple` although there is no one to one correspondence between those cases).

#4

That seems like a reasonable question. Relatedly, I filed an issue so that we don’t forget to document these rules someday.