How does the Julia Type Graph treat arrays?

Viewed 46

I'm trying to understand the structure of arrays in the Julia Type Graph. This seems very counter-intuitive to me:

julia> Int64 <: Number
true

julia> Array{Int64,1} <: Array{Number,1}
false

julia> Array{Int64,1} <: Array{Int,1}
true

It seems that a <: b is not sufficient for Array{a,1} <: Array{b,1}. When does Array{a,1} <: Array{b,1}?

A practical corollary: how can I type-declare an abstract array of numbers?

1 Answers

In the following page of the manual, it's described how julia's types are invariant as opposed to covariant. https://docs.julialang.org/en/v1/manual/types/#Parametric-Composite-Types-1

See in particular the warning admonition stating

This last point is very important: even though Float64 <: Real we DO NOT have Point{Float64} <: Point{Real}.

And the following explanation given

In other words, in the parlance of type theory, Julia's type parameters are invariant, rather than being covariant (or even contravariant). This is for practical reasons: while any instance of Point{Float64} may conceptually be like an instance of Point{Real} as well, the two types have different representations in memory:

  • An instance of Point{Float64} can be represented compactly and efficiently as an immediate pair of 64-bit values;

  • An instance of Point{Real} must be able to hold any pair of instances of Real. Since objects that are instances of Real can be of arbitrary size and structure, in practice an instance of Point{Real} must be represented as a pair of pointers to individually allocated Real objects.

An abstract array with any kind of number is denoted like this AbstractArray{<:Number} which is short for AbstractArray{T} where T <: Number

Related