Calling Base.show() with UnionAll types with unnamed type parameters prints those type parameters with non-syntactic generated names:
julia> Vector{<:Bool}
Array{#s16,1} where #s16<:Bool
This of course cannot be evaluated, which can be difficult when trying to understand a very large type that's printed in an error message, for example.
My first thought was that this should be fixed following the same approach as in https://github.com/JuliaLang/julia/pull/32408: we should change these to print via the var"" syntax, a la:
julia> Vector{<:Bool}
Array{var"#s16",1} where var"#s16"<:Bool
That seems like a fine approach, but then I noticed that if the variable _does_ have a name, the printing mechanism seems to be able to tweak the user-provided name to prevent conflicts with other identifiers in the type! This leads me to wonder if we can use that same smarts to just pick a standard identifier name, rather than a purposefully non-standard identifier as above?
For example, notice how the user-provided name T gets renamed to T1 when there's a conflict:
julia> NTuple
Tuple{Vararg{T,N}} where T where N
julia> NTuple{N,NTuple} where N
Tuple{Vararg{Tuple{Vararg{T,N}} where T where N,N}} where N
julia> NTuple{1,NTuple{T}} where T
Tuple{Tuple{Vararg{T1,T}} where T1} where T
Can we similarly have julia just pick some arbitrary type names like p1, p2, pN... or P1, P2, ... or _T1, _T2, etc, rather than the #s16, #s17 type names we're using now? And then if there's a conflict with an actual user-provided name, it can just adjust the name like it already does?
In fact, the existing mechanism already handles conflicts even for the generated names, so this should be a very easy change: just simplifying the generated names to be valid identifiers.
julia> Vector{<:Vector{<:Bool}}
Array{#s16,1} where #s16<:(Array{#s17,1} where #s17<:Bool)
julia> Vector{<:Vector{var"#s16"}} where var"#s16" <: Bool
Array{#s17,1} where #s17<:Array{#s16,1} where #s16<:Bool
julia> Vector{<:Vector{var"#s17"}} where var"#s17" <: Bool
Array{#s171,1} where #s171<:Array{#s17,1} where #s17<:Bool
Oh, i see now that it's more complicated than I had thought; i didn't realize those generated names are _part of the type_, not part of printing:
julia> Vector{<:Vector{<:Bool}}.var.name
Symbol("#s17")
I'm not sure if it's important that these remain non-standard identifiers for some reason? If so, perhaps the simplest fix would just be to print these via var"" syntax, even though it does make the types bigger, which is unfortunate.
Okay, just changing to print as var"#s17" was so easy, i just did that as a first pass at this: https://github.com/JuliaLang/julia/pull/34888.
I'd still prefer to change to nicer names, like _s, or p, or t, or _T or something, if you all agree that makes sense.
I guess we can leave this open for somebody to make the identifiers nicer.
From https://github.com/JuliaLang/julia/pull/34888#issuecomment-591592419:
Agreed on all counts --- this is a good improvement, but it would be better to use valid identifiers to begin with.
Does it make sense to change the names inside the type vars themselves? Is there any harm in them overlapping? It doesn't seem like it. I tried poking around in the scheme, but couldn't quite find the right place to do it. :'(
Most helpful comment
I guess we can leave this open for somebody to make the identifiers nicer.