Type parameters are treated differently based on their names

julia> Type === Type{T} where T
true

julia> Type === Type{S} where S
false

julia> Type === Type{t} where t
false

This is what I got in REPL(Julia v1.7.1, Windows10 64-bit). I got the same result running it as a file. In a fresh REPL, there is

julia> Type === Type{S} where S
false

I can get the true result if and only if using T as the type parameter. Why do they act differently? Is this a bug?

1 Like

Looks fine for me.

julia> Type == Type{T} where T
true

julia> Type == Type{S} where S
true

julia> Type == Type{t} where t
true

It is ‘===’, not ‘==’ in my code. @goerch

Hi @Ranlajetech ,

the change was intentional. I do not immediately find a good page in the reference manual, but this discusses differences between equality (==) and identity (===).

I have learnt about the difference between equality and identity, but I don’t understand why identifier T is so special in this piece of code that I can’t get true using any other parameter name. @goerch

julia> dump(Type)
UnionAll
  var: TypeVar
    name: Symbol T
    lb: Union{}
    ub: Any
  body: Type{T} <: Any

The default Type is defined using T as the type parameter symbol.

julia> dump(Type{S} where S)
UnionAll
  var: TypeVar
    name: Symbol S
    lb: Union{}
    ub: Any
  body: Type{S} <: Any

Both cases should be functionally the same , hence == holds, but since the typevar symbol is carried around they are not identical.

2 Likes

Half jokingly, maybe we should do

macro UnionAll(var, expr)
    Expr(:where, esc(expr), esc(var))
end

T = gensym()
TypeVarT = TypeVar(T)
TypeT = Type{TypeVarT}
MyType = UnionAll(TypeVarT, @UnionAll T TypeT)

MyType === MyType{T} where T

instead? BTW, for these kind of questions I always need the help of https://github.com/JuliaLang/julia/blob/master/test/subtype.jl

1 Like