I want to understand the type system of the Julia language. The following situation I find confusing:
Consider the chain of sub/super-types
Rational{Int64} <: Rational <: Real <: Number <: Any
which (in my mind) corresponds to a path in the type tree starting at the concrete type Rational{Int64}
and going up to the top. Now, if I call supertype(Rational)
I get Real
as expected. However, when I call supertype(Rational{Int64})
I get Real
, too. The supertype
function seems to 'jump' over Rational
. This seems very counter-intuitive to me.
Can anyone explain this behaviour?
In Julia, only DataType
s participate in inheritance. If a type does not have all of its generic type parameters specified, as with Rational
(short for Rational{T} where T<:Integer
), then it is not a DataType
but a UnionAll
, and since a UnionAll
is not actually a type, it does not participate in inheritance.
julia> Rational === Rational{T} where T<:Integer
true
julia> typeof.((Rational{Int}, Rational, Real))
(DataType, UnionAll, DataType)