# Find most specific type

**URL:** <https://discourse.julialang.org/t/find-most-specific-type/64528>\
**Category:** General Usage\
**Created:** [July 12, 2021, 7:12pm UTC](https://discourse.julialang.org/t/find-most-specific-type/64528 "2021-07-12T19:12:49Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [July 12, 2021, 7:12pm UTC](https://discourse.julialang.org/t/find-most-specific-type/64528/1 "2021-07-12T19:12:49Z")

</div>

given a collection of type tupels.  
Like [`Tuple{Int, Int}`, `Tuple{Integer, Integer}`, `Tuple{T, T} where T<: Real`]  
how can I find which is the most specific?

I assume julia has a fast way of doing this since this is what dispatch needs to do.  
An abusive way might be to generate a bunch of methods, and then use `@which`, and then pull off the `sig` from the method object.  
but that seems gross.

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [July 14, 2021, 12:58pm UTC](https://discourse.julialang.org/t/find-most-specific-type/64528/2 "2021-07-14T12:58:22Z")

</div>

```julia
julia> type_morespecific(a, b) = ccall(:jl_type_morespecific, Cint, (Any,Any), a, b)
type_morespecific (generic function with 1 method)

julia> types = [Tuple{Int, Int}, Tuple{Integer, Integer}, Tuple{T, T} where T<: Real, Tuple{Int, Integer}];

julia> sort(types, lt = Bool∘type_morespecific)
4-element Vector{Type}:
 Tuple{Int64, Int64}
 Tuple{Int64, Integer}
 Tuple{Integer, Integer}
 Tuple{T, T} where T<:Real

```

(thanks to @jakobnissen for linking [More about types · The Julia Language](https://docs.julialang.org/en/v1/devdocs/types/#Subtyping-and-method-sorting)) but that doesn’t necessarily give an answer to which method your input tuple would be dispatched to (e.g. consider `Tuple{Int64, Float64}`).

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [July 14, 2021, 5:16pm UTC](https://discourse.julialang.org/t/find-most-specific-type/64528/3 "2021-07-14T17:16:50Z")

</div>

Since we don’t actually need to the fully ordered list of specificity,  
just the most specific,  
I think we can maybe use the subtype operator `<:`.  
I think this is only correct because we want just the most specific, the others might be in another order,  
since `<:` only is a partial ordering. Because there are types that are neither `a<:b` nor `b<:a`.  
But anything at the bottom must not be `>:` of anything else in the list.  
Which is still not enough to to give us a unique most specific.  
But if we add the additional restriction that these are all answers to `T` in `a isa T` for some specific `a`, which is true in my case, then I think now it is enough to find use a unique most specific type, modulo ambiguity.

And that is a fair bit faster

```julia
julia> using BenchmarkTools

julia> type_morespecific(a, b) = Bool(ccall(:jl_type_morespecific, Cint, (Any,Any), a, b))
type_morespecific (generic function with 1 method)

julia> is_subtype_vs(a, b) = a <: b
is_subtype_vs (generic function with 1 method)

julia> is_subtype_ts(::Type{a}, ::Type{b}) where {a,b} = a <: b
is_subtype_ts (generic function with 1 method)

julia> const types = [Tuple{Int, Int}, Tuple{Integer, Integer}, Tuple{T, T} where T<: Real, Tuple{Int, Integer}];

julia> @btime partialsort(types, 1; lt=type_morespecific)
  1.304 μs (5 allocations: 304 bytes)
Tuple{Int64, Int64}

julia> @btime partialsort(types, 1; lt=is_subtype_vs)
  495.861 ns (3 allocations: 208 bytes)
Tuple{Int64, Int64}

julia> @btime partialsort(types, 1; lt=is_subtype_ts)
  212.740 ns (1 allocation: 112 bytes)
Tuple{Int64, Int64}

```

However, as I said this doesn’t overall give a correct ordering.

```julia
julia> @btime sort(types, lt=type_morespecific)
  1.326 μs (6 allocations: 384 bytes)
4-element Vector{Type}:
 Tuple{Int64, Int64}
 Tuple{Int64, Integer}
 Tuple{Integer, Integer}
 Tuple{T, T} where T<:Real

julia> @btime sort(types, lt=is_subtype_vs)
  515.120 ns (4 allocations: 288 bytes)
4-element Vector{Type}:
 Tuple{Int64, Int64}
 Tuple{Integer, Integer}
 Tuple{T, T} where T<:Real
 Tuple{Int64, Integer}

julia> @btime sort(types, lt=is_subtype_ts)
  225.705 ns (2 allocations: 192 bytes)
4-element Vector{Type}:
 Tuple{Int64, Int64}
 Tuple{Integer, Integer}
 Tuple{T, T} where T<:Real
 Tuple{Int64, Integer}

```

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [July 14, 2021, 5:23pm UTC](https://discourse.julialang.org/t/find-most-specific-type/64528/4 "2021-07-14T17:23:56Z")

</div>

That’s what I tried to use initially, but:

```julia
julia> Tuple{Integer, Integer} <: Tuple{T, T} where T<: Real
false

julia> type_morespecific(Tuple{Integer, Integer}, Tuple{T, T} where T<: Real)
true

```

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [July 14, 2021, 5:37pm UTC](https://discourse.julialang.org/t/find-most-specific-type/64528/5 "2021-07-14T17:37:12Z")

</div>

Ah i see, yeah.

That is still a problem even for a set of methods that follow my

> But if we add the additional restriction that these are all answers to `T` in `a isa T` for some specific `a` , which is true in my case, then I think now it is enough to find use a unique most specific type, modulo ambiguity.
