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:
 [1] f1(::YY) at ./REPL[3]:1
 [2] top-level scope at REPL[5]: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:
 [1] f3(::Sym{Number}) at ./REPL[2]:1
 [2] top-level scope at REPL[5]: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.