Search code examples
typesjulia

Understanding parametric types and their super-types in Julia


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?


Solution

  • In Julia, only DataTypes 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)