I'm learning Julia and thought it would be great to see the type hierarchy easily. The subtypes
function is great but it only shows one level. So I created a simple function that prints the entire subtree. Would it be good to add to Base?
julia> function subtypetree(t, level=1, indent=4)
level == 1 && println(t)
for s in subtypes(t)
println(join(fill(" ", level * indent)) * string(s))
subtypetree(s, level+1, indent)
end
end
subtypetree (generic function with 3 methods)
julia> subtypetree(Number)
Number
Complex
Real
AbstractFloat
BigFloat
Float16
Float32
Float64
Integer
BigInt
Bool
Signed
Int128
Int16
Int32
Int64
Int8
Unsigned
UInt128
UInt16
UInt32
UInt64
UInt8
Irrational
Rational
will need to write a little bit of error handling code to be production ready
I do sometimes want to see this kind of tree โย could potentially go in Meta
?
Would be even nicer using Unicode box-drawing characters to print a tree.
julia> dump(Number)
Number
Complex{T<:Real}
Base.Complex128 = Complex{Float64}
Base.Complex32 = Complex{Float16}
Base.Complex64 = Complex{Float32}
Base.FastMath.ComplexTypes = Union{Complex{Float32}, Complex{Float64}}
Base.HWNumber = Union{Float32, Float64, Int16, Int32, Int64, Int8, UInt16, UInt32, UInt64, UInt8, Complex{#s55} where #s55<:Union{Float32, Float64, Int16, Int32, Int64, Int8, UInt16, UInt32, UInt64, UInt8}, Rational{#s54} where #s54<:Union{Float32, Float64, Int16, Int32, Int64, Int8, UInt16, UInt32, UInt64, UInt8}}
Base.LinAlg.BlasComplex = Union{Complex{Float32}, Complex{Float64}}
Base.LinAlg.BlasFloat = Union{Complex{Float32}, Complex{Float64}, Float32, Float64}
Base.ScalarIndex = Real
Base.ViewIndex = Union{Real, AbstractArray}
...
~/julia$ ./julia examples/typetree.jl
+- Any << abstract immutable >>
. +- AbstractArray{T,2} << abstract immutable >>
. . +- Core.AbstractArray{T, N} = AbstractArray
. . +- Core.Inference.AbstractMatrix{T} = AbstractArray{T,2} where T
. . +- Base.AbstractMatrix{T} = AbstractArray{T,2} where T
. . +- Base.LinAlg.AbstractQ{T} << abstract immutable >>
. . . +- Base.LinAlg.AbstractQ{T} = Base.LinAlg.AbstractQ
. . . +- Base.LinAlg.QRCompactWYQ{S,M<:(AbstractArray{T,2} where T)} << concrete immutable >>
. . . . +- Base.LinAlg.QRCompactWYQ{S, M<:(AbstractArray{T,2} where T)} = Base.LinAlg.QRCompactWYQ
. . . +- Base.LinAlg.QRPackedQ{T,S<:(AbstractArray{T,2} where T)} << concrete immutable >>
. . . . +- Base.LinAlg.QRPackedQ{T, S<:(AbstractArray{T,2} where T)} = Base.LinAlg.QRPackedQ
. . +- AbstractRange{T} << abstract immutable >>
. . . +- Base.AbstractRange{T} = AbstractRange
. . . +- LinSpace{T} << concrete immutable >>
. . . . +- Base.LinSpace{T} = LinSpace
. . . +- OrdinalRange{T,Int64} << abstract immutable >>
...
Yes, I agree these aren't exactly discoverable though.
Those are sufficiently undiscoverable and under-document that I think we should keep this issue open to track having/documenting a way to do this. In particular, I really do not think this should be part of dump
and it seems like this is a specific enough thing to warrant its own function.
I wonder if such a feature shouldn't be in a standalone package.
Maybe we should have a function which output a tree datastructure and have function for several kind of display (ASCII, Unicode with box drawing char, Graphviz tree using GraphViz.jl, Tikz tree drawing using TikzPictures.jl or using any graph/tree drawing library that some contributors could suggest here...)
AbstractTrees.jl from @Keno have ASCII formatting functions for tree
Maybe being able to output this kind of drawing automatically could be a nice feature to have https://en.wikibooks.org/wiki/Introducing_Julia/Types#Type_hierarchy
Maybe D3Trees.jl from @sisl could be considered for drawing tree.
First task is probably to create a tree from this Depth First Search (DFS) traversal. I have never achieved this kind of work previously and I don't know if there is ever a Julia package to do it simply or if it should be done. Any idea?
Would love to have this feature somewhere! Maybe a simple version (like above) in Meta and a more fancy version in a separate package.
Just for completeness, with Kenos AbstractTrees this is a three liner:
julia> using AbstractTrees
julia> AbstractTrees.children(x::Type) = subtypes(x)
julia> print_tree(Number)
Number
โโ Complex
โโ Real
โโ AbstractFloat
โ โโ BigFloat
โ โโ Float16
โ โโ Float32
โ โโ Float64
โโ AbstractIrrational
โ โโ Irrational
โโ Integer
โ โโ Bool
โ โโ Signed
โ โ โโ BigInt
โ โ โโ Int128
โ โ โโ Int16
โ โ โโ Int32
โ โ โโ Int64
โ โ โโ Int8
โ โโ Unsigned
โ โโ UInt128
โ โโ UInt16
โ โโ UInt32
โ โโ UInt64
โ โโ UInt8
โโ Rational
Most helpful comment
Just for completeness, with Kenos AbstractTrees this is a three liner: