Julia: Use typealiases in method printing?

Created on 5 Feb 2016  路  7Comments  路  Source: JuliaLang/julia

I'd like to request some speculative brain cells spent on how we print method signatures to the REPL.

Currently, we expand out all typealiases. While this policy has the advantage of producing unambiguous output, the composition of type aliases through type parameters leads to combinatorially long string representations.

A particularly egregious example in Base is eigfact!:

julia> methods(eigfact!)

#12 methods for generic function "eigfact!":

...

eigfact!{T<:Union{Complex{Float32},Complex{Float64}}}(A::Union{DenseArray{T,2},SubArray{T,2,A<:DenseArray{T<:Any,N<:Any},I<:Tuple{Vararg{Union{Colon,Int64,Range{Int64}}}},LD<:Any}}) at linalg/eigen.jl:50

eigfact!{T<:Union{Float32,Float64}}(A::Union{DenseArray{T,2},SubArray{T,2,A<:DenseArray{T<:Any,N<:Any},I<:Tuple{Vararg{Union{Colon,Int64,Range{Int64}}}},LD<:Any}}, B::Union{DenseArray{T,2},SubArray{T,2,A<:DenseArray{T<:Any,N<:Any},I<:Tuple{Vararg{Union{Colon,Int64,Range{Int64}}}},LD<:Any}}) at linalg/eigen.jl:121

eigfact!{T<:Union{Complex{Float32},Complex{Float64}}}(A::Union{DenseArray{T,2},SubArray{T,2,A<:DenseArray{T<:Any,N<:Any},I<:Tuple{Vararg{Union{Colon,Int64,Range{Int64}}}},LD<:Any}}, B::Union{DenseArray{T,2},SubArray{T,2,A<:DenseArray{T<:Any,N<:Any},I<:Tuple{Vararg{Union{Colon,Int64,Range{Int64}}}},LD<:Any}}) at linalg/eigen.jl:142

...

I estimate that only three people in the world can read the first method signature and immediately recognize that the original calling signature was

eigfact!{T<:BlasComplex}(A::StridedMatrix{T})

and it would take an eagle eye to realize that the first method takes one argument whereas the other two take two inputs each.

It would be much nicer to print something like the original method signature instead of feeling overwhelmed by C++ expression template-like verbal diarrhea. It's clear, though, that the additional bookkeeping of typealiases and matching of typealiases to method signatures is a hard problem.

display and printing speculative

Most helpful comment

For simple (non-parametric) type aliases, we could just have a hash table from the expanded type back to the alias name. But for parametric types it's not so simple. There's also the issue that the same type can have various different names and we could end up printing a different/confusing one. The only approach that seems like it would do what one expects is to remember how the type name was spelled at method definition and use that specific spelling when printing things.

All 7 comments

a couple of things that would make this one slightly less horrible but are much easier to do right now :

  • avoid printing type upper bounds of type vars when it's Any
  • put back some syntax support for tuple types and varargs inside them

the general problem of which type alias to pick for a given expanded type is as you say much harder

an infix version (using unicode ?) of Union{} would also help but I feel this will be more controversial

+1. I've thought/wanted this several times. Right now, it seems that the typealias expansion happens immediately; I wonder if it would make sense or even be possible to do the expanding at a later time, like only for compilation or something.

I think there is a special case in the show code for printing ByteString for this reason. Just having this for StridedArray would be great, but obviously a more general solution would be better.

This is a dream of mine too, as it would make JuMP errors much more succinct

For simple (non-parametric) type aliases, we could just have a hash table from the expanded type back to the alias name. But for parametric types it's not so simple. There's also the issue that the same type can have various different names and we could end up printing a different/confusing one. The only approach that seems like it would do what one expects is to remember how the type name was spelled at method definition and use that specific spelling when printing things.

Worth pointing out that saving some variant of the source text would be an alternative way of solving this. Demo:

julia> using LinearAlgebra, CodeTracking, Revise

julia> Revise.track(LinearAlgebra)

julia> m = @which eigen!(rand(3,3));

julia> ex = definition(m);

julia> ex.args[end].args[1]
:(eigen!(A::StridedMatrix{T}; permute::Bool=true, scale::Bool=true, sortby::Union{Function, Nothing}=eigsortby) where T <: BlasReal)
Was this page helpful?
0 / 5 - 0 ratings

Related issues

arshpreetsingh picture arshpreetsingh  路  3Comments

omus picture omus  路  3Comments

TotalVerb picture TotalVerb  路  3Comments

omus picture omus  路  3Comments

StefanKarpinski picture StefanKarpinski  路  3Comments