# Improving doc for display/print/show/repr/

**URL:** <https://discourse.julialang.org/t/improving-doc-for-display-print-show-repr/69124>\
**Category:** Internals & Design\
**Tags:** documentation, io\
**Created:** [October 3, 2021, 12:59am UTC](https://discourse.julialang.org/t/improving-doc-for-display-print-show-repr/69124 "2021-10-03T00:59:24Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![MA\_Laforge](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ma_laforge/32/385_2.png) [@MA\_Laforge](https://discourse.julialang.org/u/MA_Laforge)\
**Post date:** [October 3, 2021, 12:59am UTC](https://discourse.julialang.org/t/improving-doc-for-display-print-show-repr/69124/1 "2021-10-03T00:59:24Z")

</div>

Continuing on what was started in (wrong forum?) [Julep: extended proposal for fixing show, print, & friends · Issue #14052 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/14052#issuecomment-927458219)

## Questions

- Why would we use `repr()` over `string()`?
  - Clearly, the call stack is different (`sprint` vs `print_to_string`) — but I can’t figure out why.

- Why does `print()` drop `::MIME` in the `print` layer — instead of delegating that choice to the `show` layer?

* * *

# A little background information

## Peering into the `display`/`print`/`show` system

Using the following to probe into specific call stacks:

```julia
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

```julia
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

```julia
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

```julia
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

```julia
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()`):

```julia
display(::SomeObj) -> display(::TextDisplay, ::SomeObj) -> display(::TextDisplay, ::MIME"text/plain", ::SomeObj)

```

Which would typically then call an appropriate MIME-aware `show()` function, for example:

```julia
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:

```julia
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 breaking `display()` system.

---

<div class="post-metadata">

**Author:** ![akb](https://avatars.discourse-cdn.com/v4/letter/a/5daacb/32.png) [@akb](https://discourse.julialang.org/u/akb)\
**Post date:** [October 3, 2021, 2:32am UTC](https://discourse.julialang.org/t/improving-doc-for-display-print-show-repr/69124/2 "2021-10-03T02:32:31Z")

</div>

I agree some work is still needed in this area.

> [@MA\_Laforge](#):
>
> Why would we use `repr()` over `string()` ?

The difference between `repr("a") == "\"a\""` and `string("a") == "a"` seems right to me.

However, as I wrote in [Distinguish string functions for data values vs programmer information · Issue #40779 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/40779#issuecomment-848443452) I do think there remains some issues here — though it may be necessary to wait till 2.0 to fix them. In particular, the idea of “printing the value itself” seems inapplicable to most types and usages of `print(x)` and `string(x)` are likely to be bugs for those types – the exceptions being String, Int, and some others.

---

<div class="post-metadata">

**Author:** ![MA\_Laforge](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ma_laforge/32/385_2.png) [@MA\_Laforge](https://discourse.julialang.org/u/MA_Laforge)\
**Post date:** [December 14, 2021, 4:00am UTC](https://discourse.julialang.org/t/improving-doc-for-display-print-show-repr/69124/3 "2021-12-14T04:00:22Z")

</div>

Sorry. Got sidetracked when I first outlined this issue - haven’t have much time to look deeper into it. Decided to include graphical view of call stack before I forget I made it (for a second time):

 ![JuliaDisplay](https://global.discourse-cdn.com/julialang/original/3X/b/7/b7d5818e6981bf65b1435f9568782ec896de0ca1.gif)

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 2, 2024, 9:01pm UTC](https://discourse.julialang.org/t/improving-doc-for-display-print-show-repr/69124/4 "2024-04-02T21:01:48Z")

</div>

Quick summary, since this thread never seems to have concluded.

`string` calls `print` (as documented [here](https://docs.julialang.org/en/v1/base/strings/#Base.string)) which (by default) calls the 2-argument `show` (documented [here](https://docs.julialang.org/en/v1/base/io-network/#Base.print), though it doesn’t say 2-arg specifically).

`display` (by default, in the REPL) calls the 3-argument `show` with text/plain which (by default) calls 2-argument `show`. Documented in the manual’s section on [custom pretty-printing](https://docs.julialang.org/en/v1/manual/types/#man-custom-pretty-printing).

1-arg `repr` calls 2-arg `show` (documented [here](https://docs.julialang.org/en/v1/base/strings/#Base.repr-Tuple%7BAny%7D), though it doesn’t mention 2-arg specifically), and 2-arg `repr` (documented [here](https://docs.julialang.org/en/v1/base/io-network/#Base.repr-Tuple%7BMIME,%20Any%7D)) calls 3-arg `show`.

(This can all be overloaded, of course — one big exception to the above rules is for strings, in which case `show` and hence `repr` add quotation marks and backslash escaping of special characters, whereas `print` just outputs the raw string. This is mentioned in the `print` docs.)

The big omission from the docs is that the `print` and 1-arg `repr` functions just say that they call `show`, but should specifically say that they call the 2-argument `show`. I think this is because those functions pre-date the 3-arg `show`. PR to fix this omission: [document that print(x) and repr(x) call 2-arg show by stevengj · Pull Request #53927 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/53927)
