Continuing on what was started in (wrong forum?) https://github.com/JuliaLang/julia/issues/14052#issuecomment-927458219
Questions
- Why would we use
repr()
overstring()
?- Clearly, the call stack is different (
sprint
vsprint_to_string
) — but I can’t figure out why.
- Clearly, the call stack is different (
- Why does
print()
drop::MIME
in theprint
layer — instead of delegating that choice to theshow
layer?
A little background information
Peering into the display
/print
/show
system
Using the following to probe into specific call stacks:
Base.show(io::IO, o::SomeObj) = throw("Dump Call Stack: No MIME")
#Base.show(io::IO, ::MIME"text/plain", o::SomeObj) = throw("Dump Call Stack: MIME")
Observations: Julia print/display system
show()
call stacks
show(::SomeObj) -> show(::IO, ::SomeObj)
show(::MIME, ::SomeObj) -> NO IMPLEMENTATION! (that's fine; ::IO is simply required)
show(::IO, ::MIME, ::SomeObj) -> show(::IO, ::SomeObj) #Default behaviour
NOTE:
- Might want to implement
show(::IO, ::MIME"text/plain", ::SomeObj)
for pretty printing
print()
call stacks
print(::SomeObj) -> print(::IO, ::SomeObj) -> show(::IO, ::SomeObj)
print(::MIME, ::SomeObj) -> print(stdout::IO, ::MIME, ::SomeObj) -> print(::IO, ::SomeObj) -> show(::IO, ::SomeObj)
print(::IO, s::STRING) -> write(::IO, s) #BYPASS SHOW COMPLETELY FOR STRINGS
NOTE:
-
Doesn’t use
show(::IO, ::MIME"text/plain", ::SomeObj)
for pretty printing (even if::MIME
is specified).
WARNING: The following statements do not work in an orthogonal way:
print(MIME("text/plain"), "SomeString")
print(stdout, MIME("text/plain"), "SomeString")
They print the ::MIME
, then the ::String
. They do not use ::MIME
to specialize formatting of print()
.
repr()
call stacks
repr(::SomeObj; context) -> sprint(::Function{show}, ::SomeObj; context) -> show(::IO, :SomeObj)
repr(::MIME, ::SomeObj; context) -> show(::IO, ::MIME, ::SomeObj) -> show(::IO, ::SomeObj)
NOTE:
- Uses
show(::IO, ::MIME"text/plain", ::SomeObj)
for pretty printing if::MIME
is provided.
string()
call stacks
string(::SomeObj) -> print_to_string(::SomeObj) -> print(::IO, ::SomeObj) -> show(::IO, ::SomeObj)
string(::MIME, ::SomeObj) -> print_to_string(::MIME, ::Vararg) -> print(::IO, ::SomeObj) -> show(::IO, ::SomeObj)
NOTE:
-
Doesn’t use
show(::IO, ::MIME"text/plain", ::SomeObj)
for pretty printing (even if::MIME
is specified).
display()
call stacks
With a TextDisplay <: Base.AbstractDisplay
@ top of display stack (see pushdisplay()
):
display(::SomeObj) -> display(::TextDisplay, ::SomeObj) -> display(::TextDisplay, ::MIME"text/plain", ::SomeObj)
Which would typically then call an appropriate MIME-aware show()
function, for example:
show(::IO, ::MIME"text/plain", ::SomeObj) -> show(::IO, ::SomeObj) #Default fallback
NOTE:
- Thus, a user-defined type should explicitly define said MIME-aware
show()
function for “pretty-printing”:show(::IO, ::MIME"text/plain", ::SomeObj)
- Fancier displays (ex: Jupyter notebooks) might support richer
::MIME
formats by calling specialized methods, for example:show(::IO, ::MIME"text/html", ::SomeObj)
show(::IO, ::MIME"image/png", ::SomeObj)
- …
- (Specialized methods are typically implemented by the package defining
::SomeObj
)
User-defined AbstractDisplay
s
With a user-defined CustomDisplay <: Base.AbstractDisplay
@ top of display stack:
display(::SomeObj) -> display(::CustomDisplay, ::SomeObj) #NO DEFAULT IMPLEMENTATION
Thus, to work with display()
system, user must implement custom:
display(::CustomDisplay, ::Any)
- and/or
display(::CustomDisplay, ::SomeObj)
WARNING:
-
display(::SomeObj)
never to be implemented directly for risk of breakingdisplay()
system.