# Dispatch Question

``````abstract type Def{T} end

struct YY <: Def{Number}
end

f1(x::Def{<:T}) where T = T
f2(x::Def{T}) where T = T

julia> f1(YY())
ERROR: UndefVarError: T not defined
Stacktrace:
 f1(::YY) at ./REPL:1
 top-level scope at REPL:1

julia> f2(YY())
Number
``````

Why f1(YY()) doesn’t work?

But the following works:

``````julia> struct Sym{T}
end

julia> f3(x::Sym{<:T}) where T = T
f3 (generic function with 1 method)

julia> f4(x::Sym{T}) where T = T
f4 (generic function with 1 method)

julia> f3(Sym{Float64}())
Float64

julia> f4(Sym{Float64}())
Float64
``````

No answer here, but interested: what are f1 and f3 for?

Also:

``````julia> f3(Sym{Number}())
ERROR: UndefVarError: T not defined
Stacktrace:
 f3(::Sym{Number}) at ./REPL:1
 top-level scope at REPL:1

``````
1 Like

Actually, they work the same:

``````julia> f3(Sym{Number}())
ERROR: UndefVarError: T not defined
``````

In the definitions of `f1` and `f3`, we have something like: “the parameter of the input type is a subtype of T. Return T”. No further information is given about what T is or could be, so what should be returned? You could argue that the answer is `Any`, but I think it makes more sense to interpret this as an error, which is what’s happening. `f2` and `f4` make sense (“return the parameter of the input’s type”).

As a sidenote, for `Def` and `YY`, you probably meant (although I could be wrong)

``````struct YY{T<:Number} <: Def{T} end
``````

I.e. keeping the type parameter on YY, but making sure it is always a subtype of a `Number`. By restricting to an abstract type like you were doing (i.e. `Def{Number}` rather than `Def{<:Number}`) you might be losing some performance and/or flexibility in your application of this type that parameterized types can give.

4 Likes

It works on my Julia. And it still doesn’t answer my question, why it works on a struct (concrete type) but doesn’t work on a abstract type (Number)?

Thanks

I think that’s not really well defined. You’re asking for a type which is a supertype of `Number`. `T=Number` is an answer, but so is `T=Any`. I’m a bit surprised that it’s not an error, but maybe it’s hard to circumscribe when to throw the error.

1 Like

Honestly, I don’t know why `f3(Sym{Float64}())` works. As far as I can tell, it’s equally nonsensical…

2 Likes

Agreed, seems like a valid issue to post / look for on the julia github.

1 Like

It is not nonsensical it does what it does it returns you the least upper bound. Which comes handy in dealing with covariant types. But the issue occurs when T is abstract type.