Open ChrisRackauckas opened 4 years ago
Maybe we can use the compact flag for this?
I had a version at some point where I just saved the last stack trace in a variable that could be printed with something like Base.reprint_trace()
. Such a function could then easily take an argument that cuts types short after a character limit. I didn't keep it because I anticipated that people would find it dangerous to just cut out information, especially if newer users copy paste that and there's no way to retrieve the full information anymore.
We've talked in the distant past about having an automatic variable like ans
at the REPL that retrieves the last error values printed by typing errs
Where it's been implemented, showarg
has been really successful for values. We could introduce a type-variant of showarg
, perhaps?
julia> A = rand(3, 5);
julia> v = view(A, 1:2, :);
julia> typeof(v)
SubArray{Float64,2,Array{Float64,2},Tuple{UnitRange{Int64},Base.Slice{Base.OneTo{Int64}}},false}
julia> summary(v) # this is thanks to `showarg`
"2×5 view(::Array{Float64,2}, 1:2, :) with eltype Float64"
So what about something like typeof(view(::Array{Float64,2}, 1:1, :))
? The part I don't like is the 1:1
, but I'm not sure what to do about that. typeof(view(::Array{Float64,2}, ::UnitRange{Int}, :))
is maybe clearer but also taking us back to where we started.
Is there a way to omit type parameters? I think a lot of issues like https://github.com/JuliaLang/julia/issues/36026 are hitting great points, but they are missing the key issue with stack traces because they are focused too much on minimal examples. Let's take a look at a very common example seen in the wild. Here a user uses a package function that autodiffs an un-autodiffable ODE definition:
And the error? Let me post it so we can fully understand its glory:
It's absolutely fantastic that Julia gives you all of the information in the world, letting you know everything about the problem all of the way down because it's all implemented in Julia. But... it's daunting. For most people, this is only harmful because there's too much information clouding what's really the issue.
The Core Issue
I tried to put a Dual number into a container for Floats. But Julia doesn't tell me this, it tells me I tried to put a
ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.UJacobianWrapper{ODEFunction{true,typeof(lorenz),UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing},Float64,DiffEqBase.NullParameters},Float64},Float64,3}
into a container for floats. Is all of that necessary to the average user? I think there should probably be a way to limit this information, i.e.ForwardDiff.Dual{...}
.However, it's not as simple as just doing that to all type parameters since here we wanted to know that it's:
so we need to print the
Float64
but omit the other part.Remedy
My proposed remedy is a system like
show_simplified_type
where a package can choose the simplified printing form of its type. SoForwardDiff.Dual
can defineForwardDiff.Dual{...,Float64}
as its simplified print out, and by default this is all that's shown. Then in the expanded stacktrace forms of https://github.com/JuliaLang/julia/issues/36026 it could be set to give the entire information, but I think this will be a lot more helpful for the vast majority of people.