# Trying to figure out parametric dispach

**URL:** <https://discourse.julialang.org/t/trying-to-figure-out-parametric-dispach/70860>\
**Category:** New to Julia\
**Tags:** parametric-types\
**Created:** [November 3, 2021, 10:02am UTC](https://discourse.julialang.org/t/trying-to-figure-out-parametric-dispach/70860 "2021-11-03T10:02:59Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![dodoplus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dodoplus/32/30148_2.png) [@dodoplus](https://discourse.julialang.org/u/dodoplus)\
**Post date:** [November 3, 2021, 10:03am UTC](https://discourse.julialang.org/t/trying-to-figure-out-parametric-dispach/70860/1 "2021-11-03T10:03:00Z")

</div>

Hi,

The following code:

```julia
abstract type XX{A <: Real} end

function makexx(T::Type{<:XX})
    T(6.0)
end

struct X1{A} <: XX{A}
    x::A
end
struct X2{A} <: XX{A} end
X1() = makexx(X1)
X1()

```

Crashes with:

```julia
MethodError: no method matching makexx(::Type{X1})

```

However, if I change the signature of XX to:

```julia
abstract type XX{A} end

```

works fine. Why does the first version doesn’t?

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [November 3, 2021, 11:26am UTC](https://discourse.julialang.org/t/trying-to-figure-out-parametric-dispach/70860/2 "2021-11-03T11:26:45Z")

</div>

Interesting case. Note that this works when using the `XX{A<:Real}` pattern:

```julia
julia> makexx(X1{Float64})
X1{Float64}(6.0)

```

but I don’t know why it fails with `X1` only.

My guess is that when you call the function with `makexx(X1)` you are implicitly doing `makexx(X1{Any})`, and there is no method in that case to dispatch, like this:

```julia
julia> makexx(X1{Any})
ERROR: TypeError: in XX, in A, expected A<:Real, got Type{Any}
Stacktrace:
 [1] top-level scope
   @ REPL[7]:1

```

but with a confusing error message, because you only get the type error for an anonymous type.

Note that this also solves the problem, by removing the possibility of interpreting `X1` as something which is not a subtype of `XX`:

```julia
julia> abstract type XX{A <: Real} end

julia> struct X1{A<:Real} <: XX{A} x::A end # note the <: Real here

julia> makexx(T::Type{<:XX}) = 1
makexx (generic function with 1 method)

julia> makexx(X1)
1

```

That is, the problem arises when it is possible to have a `X1` which is not a subtype of `XX{A<:Real}`. Then the function signature gets confused. Maybe it is possible to provide a better error message there?

---

<div class="post-metadata">

**Author:** ![sostock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sostock/32/5546_2.png) [@sostock](https://discourse.julialang.org/u/sostock)\
**Post date:** [November 5, 2021, 9:15am UTC](https://discourse.julialang.org/t/trying-to-figure-out-parametric-dispach/70860/4 "2021-11-05T09:15:04Z")

</div>

To add to @lmiq’s anwser: This is an open issue ([#37901](https://github.com/JuliaLang/julia/issues/37901)). The problem is

```julia
julia> X1 <: XX
false

```

Basically, `XX` is equal to `XX{<:Real}` but `X1` is equal to `X1{<:Any}`. So `X1` also includes types like `X1{String}` (even though such a type cannot be instantiated), which is not a subtype of `XX`.

```julia
julia> X1 <: XX{<:Any}
true

julia> X1{<:Real} <: XX
true

```

Like @lmiq said, the easiest solution would be to define

```julia
struct X1{A<:Real} <: XX{A}
    x::A
end
struct X2{A<:Real} <: XX{A} end

```

(with `A<:Real` instead of just `A`). In that case you have `X1 <: XX` so that `makexx(X1)` will work.
