Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

show for UnionAll types prints non-syntactic identifiers for unnamed type variables #34887

Closed
NHDaly opened this issue Feb 26, 2020 · 4 comments · Fixed by #39395
Closed

show for UnionAll types prints non-syntactic identifiers for unnamed type variables #34887

NHDaly opened this issue Feb 26, 2020 · 4 comments · Fixed by #39395
Labels
display and printing Aesthetics and correctness of printed representations of objects.

Comments

@NHDaly
Copy link
Member

NHDaly commented Feb 26, 2020

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 #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
@NHDaly
Copy link
Member Author

NHDaly commented Feb 26, 2020

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.

@NHDaly
Copy link
Member Author

NHDaly commented Feb 26, 2020

Okay, just changing to print as var"#s17" was so easy, i just did that as a first pass at this: #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.

@JeffBezanson JeffBezanson added the display and printing Aesthetics and correctness of printed representations of objects. label Feb 26, 2020
@Keno Keno closed this as completed Feb 26, 2020
@Keno Keno reopened this Feb 26, 2020
@Keno
Copy link
Member

Keno commented Feb 26, 2020

I guess we can leave this open for somebody to make the identifiers nicer.

@NHDaly
Copy link
Member Author

NHDaly commented Feb 27, 2020

From #34888 (comment):

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. :'(

stev47 added a commit to stev47/julia that referenced this issue May 3, 2020
fixes JuliaLang#34887

typevars with gensym symbols will now be printed inlined for
`UnionAll` type arguments if their type bounds allow to do so (i.e.
`<:UB` or `>:LB`).
typevars with named symbols are printed as before since they are assumed
to carry meaning and thus might be helpful.

Before:

  julia> Ref{<:Any}
  Ref{var"#s2"} where var"#s2"
  julia> Ref{<:Ref{<:Ref}}
  Ref{var"#s1"} where var"#s1"<:(Ref{var"#s2"} where var"#s2"<:Ref)

After:

  julia> Ref{<:Any}
  Ref
  julia> Ref{<:Ref{<:Ref}}
  Ref{<:Ref{<:Ref}}
stev47 added a commit to stev47/julia that referenced this issue May 5, 2020
fixes JuliaLang#34887

typevars in unionall type arguments can now be printed inlined if their
type bounds allow to do so (e.g. `<:UB` or `>:LB`).
typevars with named symbols are printed verbosely as before unless
`:compact => true` is set in the IOContext.

Before:

  julia> Ref{<:Any}
  Ref{var"#s2"} where var"#s2"
  julia> Ref{<:Ref{<:Ref}}
  Ref{var"#s1"} where var"#s1"<:(Ref{var"#s2"} where var"#s2"<:Ref)

After:

  julia> Ref{<:Any}
  Ref
  julia> Ref{<:Ref{<:Ref}}
  Ref{<:Ref{<:Ref}}
stev47 added a commit to stev47/julia that referenced this issue May 5, 2020
fixes JuliaLang#34887

typevars in unionall type arguments can now be printed inlined if their
type bounds allow to do so (e.g. `<:UB` or `>:LB`).
typevars with named symbols are printed verbosely as before unless
`:compact => true` is set in the IOContext.

Before:

  julia> Ref{<:Any}
  Ref{var"#s2"} where var"#s2"
  julia> Ref{<:Ref{<:Ref}}
  Ref{var"#s1"} where var"#s1"<:(Ref{var"#s2"} where var"#s2"<:Ref)

After:

  julia> Ref{<:Any}
  Ref
  julia> Ref{<:Ref{<:Ref}}
  Ref{<:Ref{<:Ref}}
stev47 added a commit to stev47/julia that referenced this issue May 14, 2020
fixes JuliaLang#34887

typevars in unionall type arguments can now be printed inlined if their
type bounds allow to do so (e.g. `<:UB` or `>:LB`).
typevars with named symbols are printed verbosely as before unless
`:compact => true` is set in the IOContext.

Before:

  julia> Ref{<:Any}
  Ref{var"#s2"} where var"#s2"
  julia> Ref{<:Ref{<:Ref}}
  Ref{var"#s1"} where var"#s1"<:(Ref{var"#s2"} where var"#s2"<:Ref)

After:

  julia> Ref{<:Any}
  Ref
  julia> Ref{<:Ref{<:Ref}}
  Ref{<:Ref{<:Ref}}
stev47 added a commit to stev47/julia that referenced this issue May 30, 2020
fixes JuliaLang#34887

typevars in unionall type arguments can now be printed inlined if their
type bounds allow to do so (e.g. `<:UB` or `>:LB`) and they are not
referenced from elsewhere in the type hierarchy.

Before:

  julia> Ref{<:Any}
  Ref{var"#s2"} where var"#s2"
  julia> Ref{<:Ref{<:Ref}}
  Ref{var"#s1"} where var"#s1"<:(Ref{var"#s2"} where var"#s2"<:Ref)

After:

  julia> Ref{<:Any}
  Ref
  julia> Ref{<:Ref{<:Ref}}
  Ref{<:Ref{<:Ref}}
stev47 added a commit to stev47/julia that referenced this issue May 30, 2020
fixes JuliaLang#34887

typevars in unionall type arguments can now be printed inlined if their
type bounds allow to do so (e.g. `<:UB` or `>:LB`) and they are not
referenced from elsewhere in the type hierarchy.

Before:

  julia> Ref{<:Any}
  Ref{var"#s2"} where var"#s2"
  julia> Ref{<:Ref{<:Ref}}
  Ref{var"#s1"} where var"#s1"<:(Ref{var"#s2"} where var"#s2"<:Ref)

After:

  julia> Ref{<:Any}
  Ref
  julia> Ref{<:Ref{<:Ref}}
  Ref{<:Ref{<:Ref}}
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.
Projects
None yet
3 participants