Skip to content

Feature suggestion: a new Union like construct aka Type List #22404

@rfourquet

Description

@rfourquet

There are two issues that this new construct, call it List, would solve (for which Union kinda works but is imperfect) :

  1. Getting the same "priority" in dispatch resolution as when unrolling the types with @eval:
julia> f(::AbstractSet, ::Int) = 1 ;

julia> f(::Set, ::Union{Int,UInt}) = 2 ;

julia> f(Set(), 1)
ERROR: MethodError: f(::Set{Any}, ::Int64) is ambiguous. Candidates:
  f(::Set, ::Union{Int64, UInt64}) in Main at REPL[2]:1
  f(::AbstractSet, ::Int64) in Main at REPL[1]:1
Possible fix, define
  f(::Set, ::Int64)

Well, I don't plan to define f(::Set, ::Int). What I really mean with the second definition is

for T = (Int, UInt)
    @eval f(::Set, ::$T) = 2
end

Here, I propose to have f(::Set, ::List{Int,UInt}) be equivalent to the above.

  1. Avoid subtle bugs when forgetting that more than N types match Union{A1,...,AN}
    Cf. for example replace types of Union with Union of types in some places #22403.
julia> f(a::Vector{<:Union{Int,UInt}) = ... # unsafe operation involving e.g. sizeof(eltype(a))

julia> f(Union{Int,UInt}[1]) # crash! the correct way to define `f` was:

julia> f(a::Union{Vector{Int},Vector{UInt}}) = ... # which becomes more and more verbose with more types in the Union

julia> f(::Type{<:Union{Int,UInt}}) = ... # another example

julia> f(Union{Int,UInt}) # unexpected call

Admitedly, these bugs are probably rarely met in practice, but List{Int,UInt} could do the trick.

Metadata

Metadata

Assignees

No one assigned

    Labels

    speculativeWhether the change will be implemented is speculativetypes and dispatchTypes, subtyping and method dispatch

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions