This question builds on What is difference between Type{T} and T - #16 by Henrique_Becker
Are there any objections to the definition below?
Based on the following two quotes from Types · The Julia Language
One particularly distinctive feature of Julia’s type system is that concrete types may not subtype each other: all concrete types are final and may only have abstract types as their supertypes.
When the type is abstract, it suffices for the value to be implemented by a concrete type that is a subtype of the abstract type.
Definition: Object x is an instance of the abstract type y if, and only if, the concrete type t_x of x and the value v_y of y satisfy t_x <: v_y.
Note that, according to this definition, Type
is an instance of itself because
julia> typeof(Type)
UnionAll
julia> UnionAll <: Type
true
Moreover, this definition works with examples like Type{Float64}
. It is an instance of Type
because typeof(Type{Float64}) = DataType
and DataType <: Type
both hold.
But UnionAll
is not an instance of itself
julia> typeof(UnionAll)
DataType
julia> DataType <: UnionAll
false
Indeed, via the same argument, no type in the chain (Int64, Signed, Integer, Real, Number)
is an instance of itself.
Whilst I am comfortable with the above, the Ptr
provides a potential counterexample because, according to the manual it has “instances” such as Ptr{Int64}
and Ptr{Float64}
. But
julia> typeof(Ptr{Float64})
DataType
julia> DataType <: Ptr
false
and
julia> isa(Ptr{Float64},Ptr)
false
Personally, I like definition at the top of this post as I can imagine applying it in the field. There are two ways to rescue it:
- say that
Ptr
is not an abstract type. Is this reasonable? If so, then is it concrete, or can parametric types be neither abstract, nor concrete? - say that
Ptr{Int64}
is not an instance ofPtr
. This would fit the observation thatPtr
has no subtypes, but not the observation thatPtr{Int64} <: Ptr
holds. (I am putting this latter contradiction in a separate topic.)