```
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.