Closed tk3369 closed 3 years ago
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
I've written my own function
with similar functionality a while ago. Today I've felt the need for that again and searched to check whether such a package exist and came across this discussion.
I've then adapted my old code into a standalone, modest package (which will likely remain plain and simple), which is now in the process of registration, so that others can discover, easily ] add
and use.
The registration PR (which contains link to the original repo) is HERE.
Usage example:
julia> using TypeTree
julia> tt(Number, concrete=false) # filters off concrete types
7-element Vector{String}:
"Number\n"
" └─ Real\n"
" ├─ AbstractFloat\n"
" ├─ AbstractIrrational\n"
" └─ Integer\n"
" ├─ Signed\n"
" └─ Unsigned\n"
Moreover, join
and print
can be used as to produce a pretty print:
julia> print(join(tt(Signed), "")) # includes all concrete/abstract subtypes
Signed
├─ BigInt
├─ Int128
├─ Int16
├─ Int32
├─ Int64
└─ Int8
And Unicode
can be avoided with:
julia> print(join(tt(Unsigned, uni=false), ""))
Unsigned
+-- UInt128
+-- UInt16
+-- UInt32
+-- UInt64
\-- UInt8
With a package existing that perfectly implements the functionality requested here, I think this can be closed (again).
A bit late to the party here, but Term now provides functionality very much like the one discussed above, see [here]: https://fedeclaudi.github.io/Term.jl/stable/ren/tree/#TypeTree
Thank you, Frederico, and nice package!
Best regards,
@cnaak, please be careful when posting to GitHub via email with a signature—you are effectively posting all your personal details on the internet. I have edited your comment to remove the signature.
@cnaak, please be careful when posting to GitHub via email with a signature—you are effectively posting all your personal details on the internet. I have edited your comment to remove the signature.
Thank you @StefanKarpinski , the edit was so kind of you! Really appreciated!!
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?