Overriding Base.show for Int64 causes madness

Dear all,

I am dumbstruck. I just tried the pointless endeavour overriding Base.show for Int64. This is what I did (REPL):

julia> import Base.show
julia> Base.show(io::IO, x::Int64) = println("Hello. I am $x")
julia> q = 1

The output is:

_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2237 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2419
display_error at ./client.jl:107
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2237 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2419
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1703 [inlined]
jl_f__call_latest at /buildworker/worker/package_linux64/build/src/builtins.c:714
#invokelatest#2 at ./essentials.jl:708 [inlined]
invokelatest at ./essentials.jl:706 [inlined]
_start at ./client.jl:487
jfptr__start_34289.clone_1 at /home/lorenzo/bin/julia-1.6.1/lib/julia/sys.so (unknown line)
_jl_invoke at /buildworker/worker/package_linux64/build/src/gf.c:2237 [inlined]
jl_apply_generic at /buildworker/worker/package_linux64/build/src/gf.c:2419
jl_apply at /buildworker/worker/package_linux64/build/src/julia.h:1703 [inlined]
true_main at /buildworker/worker/package_linux64/build/src/jlapi.c:560
repl_entrypoint at /buildworker/worker/package_linux64/build/src/jlapi.c:702
main at julia (unknown line)
__libc_start_main at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
unknown function (ip: 0x4007d8)

repeated thousands of times, during which I am essentially locked out of the terminal.
So the question, of course, is… what gives?

Now I am guessing this is due to the fact that "Hello. I am $x" calls Base.show in an infinitely recursive manner. What I don’t understand, however, is the output dump. Is that some sort of stacktrace due to stack smashing? It is worth noting that Julia does something for a while (silently) before dumping that garbage. Also, if that is the case, is that Julia’s normal wy of handling infinite recursion?

Any hints/confirmations would be appreciated! PS. I am using Julia 1.6.1.

1 Like

I do something like this for floats in my startup.jl file. I use @printf rather than println. Here’s an exampel

using Printf 
Base.show(io::IO, f::Float64) = @printf(io, "%1.5e", f)

The idea is that I only want five figures in the mantissa to show up on the screen.

1 Like

I suspect that interpolating an integer calls show and that is causing an infinite recursion. It’s not the whole story, though:

julia> Base.show(io::IO, x::Int64) = println("hello")

julia> q=1hello
hello
jq=1a>
hello
hello


hello
hello
julia>
1 Like

Just tried this and it seems to work

julia> Base.show(io::IO, f::Float64) = @printf(io, "%s %1.5e", "Hello ", f)

julia> sqrt(2)
Hello  1.41421e+00

julia> exp(1)
Hello  2.71828e+00

So there does not seem to be a problem with Floats. With Ints I’m seeing variations on the insanity that @mbaz reports

That’s interesting. Could it be that @printf does not use Base.show but it’s own implementation for converting numbers to strings based on the format specifiers?

Just to emphasize: This is type piracy and an especially dangerous one since this method is used in a lot of other places. It is expected that all kind of things can break if you redefine this.

5 Likes

I have no doubts about this being a ridiculously dumb idea that would probably not be any smarter than overriding arithmetic operators for Int64’s. However, the point I wanted to discuss is the direct result, not the catastrophic implications.