Thanks Simon, way better, way more Julian. -- Brian
On Saturday, September 24, 2016 at 5:12:52 PM UTC-7, Simon Danisch wrote: > > 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? >> >>