Type constructor ambiguities

I am a bit mystified by the behaviour I am seeing when creating types that inherit from StaticArrays.FieldVector:

julia> using StaticArrays

julia> struct Dummy{T} <: FieldVector{2, T}
           x::T
           y::T
       end

julia> Dummy(v::AbstractVector) = Dummy(v...)
Dummy

julia> Dummy([1,2])
2-element Dummy{Int64}:
 1
 2

julia> Dummy(SVector(1,2))
ERROR: MethodError: Dummy(::SVector{2,Int64}) is ambiguous. Candidates:
  (::Type{Dummy})(v::AbstractArray{T,1} where T) in Main at REPL[4]:1
  (::Type{SA})(a::StaticArrays.StaticArray) where SA<:StaticArrays.StaticArray in StaticArrays at /Users/dnf/.julia/v0.6/StaticArrays/src/convert.jl:4
Possible fix, define
  Dummy(::StaticArrays.StaticArray{S,T,1} where T where S<:Tuple)

The stacktrace tells me (I think) that the Dummy constructor isn’t treated as a regular function/method, but that instead, something like (pseudocode)

call(::Type{Dummy}, ::SVector)

is being invoked. In that case I see why there is an ambiguity. I do, however, find the behaviour very surprising. Even though it’s not strange that type constructors are a bit special, it seems odd that when I explicitly call Dummy(), that dispatch would not prioritize one of the Dummy() methods, if it has a matching signature.

Can someone explain the rationale behind this behaviour? It seems like an ambiguity trap, where I potentially may need special case code for all sorts of AbstractArrays that defines constructors similar to StaticArray. I’d really like to be able to create a constructor that would work on any AbstractArray, but I don’t see how that is possible.

Yep, this caught me by surprise too, see this issue: https://github.com/FugroRoames/Rotations.jl/issues/49. Your explanation is correct, the type is just another slot in the method arguments and is dispatched on accordingly. However I agree that it is confusing and that special casing constructors could make sense. Well, now is the time to file an issue, or wait for Julia 2.0 (as such a change would be breaking).

I gave it a try: https://github.com/JuliaLang/julia/issues/24723

1 Like