This sentence from the blog post should be corrected, it’s incorrect, or at least highly misleading:
Parametric types can be highly efficient when the type T
is concrete (i.e., not abstract).
The issue is that “abstract” is ambiguous, in Julia it sometimes refers to any non-concrete type, but it’s AFAIK more proper to use it to refer merely to types declared with abstract type
. The latter meaning is the one used by isabstracttype
. Thus isconcretetype
and isabstracttype
are not opposites.
EDIT (more than three consecutive replies are not allowed):
A visualization of Julia’s subtyping might also be educational. Given these example Julia types:
abstract type PointSupertype0 end
abstract type PointSupertype1{T} <: PointSupertype0 end
struct Point{T} <: PointSupertype1{T} end
types = (
Point, PointSupertype0, PointSupertype1,
PointSupertype1{Int}, PointSupertype1{<:Int},
PointSupertype1{Float64}, PointSupertype1{<:Float64},
Point{Int}, Point{<:Int}, Point{Float64}, Point{<:Float64},
Point{Union{Int, Float64}}, Point{<:Union{Int, Float64}},
Union{Point{Int}, Point{Float64}},
Union{Point{<:Int}, Point{<:Float64}},
)
… a Julia script makes a digraph from the subtyping relation, does transitive reduction on it, then produces this GraphViz Dot specification for visualizing:
digraph='
digraph {
"Point" -> "PointSupertype1"
"PointSupertype1" -> "PointSupertype0"
"PointSupertype1{<:Float64}" -> "PointSupertype1"
"PointSupertype1{<:Int64}" -> "PointSupertype1"
"PointSupertype1{Float64}" -> "PointSupertype1{<:Float64}"
"PointSupertype1{Int64}" -> "PointSupertype1{<:Int64}"
"Point{<:Float64}" -> "PointSupertype1{<:Float64}"
"Point{<:Float64}" -> "Union{Point{<:Int64}, Point{<:Float64}}"
"Point{<:Int64}" -> "PointSupertype1{<:Int64}"
"Point{<:Int64}" -> "Union{Point{<:Int64}, Point{<:Float64}}"
"Point{<:Union{Float64, Int64}}" -> "Point"
"Point{Float64}" -> "PointSupertype1{Float64}"
"Point{Float64}" -> "Point{<:Float64}"
"Point{Float64}" -> "Union{Point{Float64}, Point{Int64}}"
"Point{Int64}" -> "PointSupertype1{Int64}"
"Point{Int64}" -> "Point{<:Int64}"
"Point{Int64}" -> "Union{Point{Float64}, Point{Int64}}"
"Point{Union{Float64, Int64}}" -> "Point{<:Union{Float64, Int64}}"
"Union{Point{<:Int64}, Point{<:Float64}}" -> "Point{<:Union{Float64, Int64}}"
"Union{Point{Float64}, Point{Int64}}" -> "Union{Point{<:Int64}, Point{<:Float64}}"
}
'
printf '%s' "$digraph" | dot -Tpng > /tmp/graphviz.png
This is the result: