Why the following two methods are ambiguous?

Dear All,

I am pretty new to Julia. Going over the documentation (v1.1.1), I am struggling at Section 19.10, trying to understand why the following two method definitions for the generic function f are ambiguous:

f(::AbstractArray{T},::Number) where {T} = ...
f(::Array{T}, ::T) where {T} = ...

e.g., for f([1,2,3],1). As far as I understand, this function call matches the second method with method type parameter value T=Int64. While it also matches the first method with T=Int64, isn’t the second method with T=Int64 a more specific variant of the first method with T=Int64? (as Array{Int64} <: AbstractArray{Int64} and Int64 <: Number).

I am almost sure that I am missunderstanding sthg related to parametric methods/composite types, but I am not able to actually figure out what exactly.

Thanks a lot for your help!
Best regards,
Alberto F. Martín.

Think of the two method signatures each defining a set of applicable argument types.

Here, neither set is a subset of the other, because the T in the second one does not have to be <: Number. The fix is to define the second method as

f(::Array{T}, ::T) where {T <: Number} = 2
2 Likes

Dear @Tamas_Papp,

Thanks for your insightful response! It was very helpful.

I think I got it … just to double-check, you resolve the amibiguity by constraining the set of applicable argument types to the second parameter of the second method to be a subset of those of the second parameter of the first method … Right?

Best regards,
Alberto.

I prefer to think of the set of all argument types (ie a set of Tuples), combined for all positional arguments. Here I need to narrow the second method so that

T1 = Tuple{AbstractArray{T,N} where N, S} where {T, S <: Number}
T2 = Tuple{Array{T,N} where N, T} where {T <: Number}
T2 <: T1 # true

Those wheres inside are explained here, Tuples here.

1 Like