How about something like this:

function showtypetree(T, level=0)
    println("\t" ^ level, T)
    for t in subtypes(T)
        (t != Any) && showtypetree(t, level+1)
    end   
end

This is still not type stable, since *_subtype *seems to use untyped sets:
https://github.com/JuliaLang/julia/blob/master/base/reflection.jl#L283

Not sure if this is an oversight, or if there are actually corner cases 
making it impossible to type as Set{DataType}().
Fact is, with that change subtype is 10x faster and doesn't return 
Vector{Any} anymore.
I opened a PR:
https://github.com/JuliaLang/julia/pull/18663

Best,
Simon


Am Sonntag, 25. September 2016 00:12:16 UTC+2 schrieb Brian Rogoff:
>
> ... of @code_warntype output.
>
> I was reading 
> https://en.wikibooks.org/wiki/Introducing_Julia/Types#Investigating_types 
> and I came across the following code, described as "not very elegant":
>
> level = 0
> function showtypetree(subtype)
>     global level
>     subtypelist = filter(asubtype -> asubtype != Any, subtypes(subtype))
>     if length(subtypelist) > 0 
>          println("\t" ^ level, subtype)        
>          level += 1
>          map(showtypetree, subtypelist)
>          level -= 1
>     else
>          println("\t" ^ level, subtype)
>     end    
> end
>
> showtypetree(Number)
>
>
> Being unable to leave well enough alone, I decided to try to make it more 
> elegant. After replacing the inelegant global variable with a nested 
> function, I first noticed that the function returns '0', which is ugly. So, 
> the increment operators return a value, which is unfortunate (any reason 
> there's no increment with doesn't do that?) and the two branches of the if 
> return different types. A special 'ignore' function patches that. map also 
> builds and returns a value that's discarded. In OCaml we'd use an 'iter' 
> instead of 'map', but Julia's 'for' can be a one-liner too. I left the 
> print alone even though there's no need to repeatedly build those strings 
> (print_nchars_before is easy)  .In the end I got here
>
> ignore{T<:Any}(value::T)::Void = return
>
> function showtypetree(subtype::DataType)::Void
>     level::Int64 = 0
>     function nested(st::DataType)::Void
>         subtypelist = filter(asubtype -> asubtype != Any, subtypes(st))
>         if length(subtypelist) > 0 
>             println("\t" ^ level, st)        
>             level += 1
>             for s in subtypelist nested(s)  end
>             ignore(level -= 1)
>         else
>             println("\t" ^ level, st)
>         end    
>     end
>     nested(subtype)
> end
>
>
> I still notice that when I do @code_warntype showtypetree(Number), I get 
> some 'red', notably, level is shown as Core.Box, even though I explicitly 
> type it. Is there some way to reduce the red in the @code_warntype for this 
> function? Here's what I get in 0.6.0-dev.749
>
> julia> @code_warntype showtypetree(Number)
> Variables:
>   #self#::#showtypetree
>   subtype::Type{Number}
>   level::Core.Box
>   nested::Core.Box
>
> Body:
>   begin
>       level::Core.Box = $(Expr(:new, :(Core.Box)))
>       nested::Core.Box = $(Expr(:new, :(Core.Box)))
>       SSAValue(0) = Main.Void
>       (Core.setfield!)(level::Core.Box,:contents,0)::Int64 # line 3:
>       SSAValue(1) = $(Expr(:new, :(Main.#nested#2), :(level), :(nested)))
>       (Core.setfield!)(nested::Core.Box,:contents,SSAValue(1))::#nested#2 
> # line 16:
>       return 
> (Base.convert)(SSAValue(0),((Core.getfield)(nested::Core.Box,:contents)::Any)(subtype::Type{Number})::Any)::Void
>   end::Void
>
>
> and I'm not sure how to remove the red and make the code more elegant. 
> Ideas?
>
>

Reply via email to