Where is "Vector", "Matrix" printed in `typeof(::AbstractArray)`

I am looking for the code from Base that prints Vector or Matrix for a Vector or Matrix, and Array otherwise. I tried to track it down, and this seems to happen in typeof(::AbstractArray); but I can’t inspect that function, neither through which nor the debugger:

julia> [1]
1-element Vector{Int64}:
 1

julia> typeof([1])
Vector{Int64} (alias for Array{Int64, 1})

julia> @which typeof([1])
ERROR: ArgumentError: argument is not a generic function
Stacktrace:
 [1] which(f::Any, t::Any)
   @ Base .\reflection.jl:1320

How can I find this code?

(The reason I’m looking for it, is that I’m writing a custom showarg(io::IO, x::AbstractArray{<:Unitful.Quantity{T,D,U}}, toplevel). Calling nameof(typeof(x)) yields "Array", even for vectors and matrices. I currently do

    print(io, x isa Vector ? "Vector" :
              x isa Matrix ? "Matrix" :
              nameof(typeof(x)))

but that seems non-ideal (i.e. for Vector subtypes)).

typeof() merely returns you a type, you can skip one step:

julia> Vector{Int64}
Vector{Int64} (alias for Array{Int64, 1})

the line printed out you’re seeing comes from

julia> Vector{Int64};

julia> display(Vector{Int64});
Vector{Int64} (alias for Array{Int64, 1})

(you know this is where it comes from because ; has suppressed the normal REPL display)

and I think the easiest way is:

julia> a = [1];

julia> b = [1 2];

julia> c = [1 2;;;3 4];

julia> string(typeof(a))
"Vector{Int64}"

julia> string(typeof(b))
"Matrix{Int64}"

julia> string(typeof(c))
"Array{Int64, 3}"

display ultimately calls show(stdout, MIME("text/plain"), Vector{Int64}) as explained here. You can find the definition at:

julia> @which show(stdout, MIME("text/plain"), Vector{Int64})
show(io::IO, ::MIME{Symbol("text/plain")}, x::Type) in Base at show.jl:855

here in show.jl.

In general string(x) calls print(x), which typically calls show(io, x) (though there are some exceptions like strings that print differently). If you want the three-arg show(io, "text/plain", x) output as a string you can call repr("text/plain", x) or, most generally, sprint(show, "text/plain", x).

But it sounds like @tfiers wants the output without the type parameters but with the alias?

That is exact @stevengj.
We can split it off the string of course, but that’s not the cleanest.

Vector{T} is just a alias for Array{T, 1}, the same way that Matrix{T} is a alias for Array{T, 2}.

So if you want to make a custom print for AbstractVector and AbstractMatrix subtypes you can do it like this:

function showarg(io::IO, x::AbstractArray{<:Unitful.Quantity{T,D,U}, 1}, toplevel) 
    # code for AbstractVector
end

function showarg(io::IO, x::AbstractArray{<:Unitful.Quantity{T,D,U}, 2}, toplevel) 
    # code for AbstractMatrix
end

Or;

function showarg(io::IO, x::AbstractVector{<:Unitful.Quantity{T,D,U}}, toplevel) 
    # code
end

function showarg(io::IO, x::AbstractMatrix{<:Unitful.Quantity{T,D,U}}, toplevel) 
    # code
end

Thanks for the helpfulness y’all. What a great community.

This is indeed what I’m after:

The code to print this clearly exists somewhere in the julia codebase, I just don’t know where.
I guess I’d like to see the source code of typeof(::AbstractArray).

I gave you the link above, to the show method, and you should look there to find the lower-level code for output of types. In general, how anything in Julia is displayed or printed almost always boils down to show.

Yes, thank you. (I hadn’t actually clicked that link because I thought I knew the function it pointed to; but turned out it was a different show in Base :sweat_smile:).

Exploring that function led me to the solution:

julia> Base.make_typealias(Vector{Int})[1].name
:Vector