Skip to content

Conversation

@JeffBezanson
Copy link
Member

Lots of types have extra parameters added just for specialization and conveying no useful additional information. I have gotten requests for some way to avoid printing these to cut down type verbosity e.g. in stack traces. This PR adds a very minimal mechanism that does the job:

julia> struct Hidden{A,B,C}
           x::A
       end

julia> Core.typename(Hidden).relevant_params = 1
1

julia> error(Hidden{Int,String,String}(1))
ERROR: Hidden{Int64, String, String}(1)
Stacktrace:
 [1] error(s::Hidden{Int64, …})
   @ Base ./error.jl:54
 [2] top-level scope
   @ REPL[4]:1
Some type information was truncated. Use `show(err)` to see complete types.

Note the limit is only applied inside the stack trace and not the exception, but that's an orthogonal feature that could be changed.

It might seem a bit un-principled to just cram a mutable integer field in there; we wouldn't necessarily want this changing all the time. Nevertheless I think this is a pretty efficient and effective way to do this. Using methods would be way too heavyweight. But, we might want to make the field constant and only set once when the type is defined, and have some macro syntax for specifying this.

@JeffBezanson JeffBezanson added needs tests Unit tests are required for this change needs docs Documentation for this change is required display and printing Aesthetics and correctness of printed representations of objects. labels May 12, 2025
@ChrisRackauckas
Copy link
Member

This would be absolutely amazing to have in Base.

@adienes
Copy link
Member

adienes commented May 12, 2025

why change the approach from #48444 ? is it so making a type "quiet" can happen by a third party outside of the declaration?

@JeffBezanson
Copy link
Member Author

That needed a re-do since then we didn't even have the stacktrace_types_limited flag yet, plus this is more general since you can specify how many parameters to print.

I don't want third parties to be able to set this, no, but it's also not particularly harmful.

@tecosaur
Copy link
Member

Apologies if this is beyond the scope of this PR, but I'm reminded of #269, for which the workaround seems to be doing something like this:

struct _IndirectFoo{_B}
    a::_B
end

struct Bar
    b::_IndirectFoo{Bar}
end

const Foo = _IndirectFoo{Bar}

However this then means instead of MyModule.Foo you see MyModule._IndirectFoo{MyModule.Bar} which is similarly unhelpful to the extra parameters you mention here.

@kunzaatko
Copy link
Contributor

kunzaatko commented May 22, 2025

What types from Base do you suggest would use this field? I am asking because for instance a SubArray and Slices, two types with a similar purpose, have a completely different order of type parameters

Slices{P,SM,AX,S,N} <: AbstractSlices{S,N}
SubArray{T,N,P,I,L} <: AbstractArray{T,N}

and there are other such examples.
So for instance a use that would only show the dimensionality and element type would necessitate changing these and that would brake a lot of code...

If this were to be avoided, then a better implementation would seem to be having a field of a staticly sized bitarray in the data type that would allow to filter out the type parameters that someone wants to print... Since most types do not have more than 8 type parameters anyway, it would not be at the cost of additional memory, correct?

@JeffBezanson
Copy link
Member Author

Yes, we could make it a bit vector instead, that might be a good idea.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

display and printing Aesthetics and correctness of printed representations of objects. needs docs Documentation for this change is required needs tests Unit tests are required for this change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants