Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Edit of "Output-function summary" docs from a new learner #56767

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Changes from 18 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 65 additions & 9 deletions doc/src/manual/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -1590,15 +1590,71 @@ to adjust printing.
### Output-function summary

Here is a brief summary of the different output functions in Julia and how they are related.
Most new types should only need to define `show` methods, if anything.

* [`display(x)`](@ref) tells the current environment to display `x` in whatever way it thinks best. (This might even be a graphical display in something like a Jupyter or Pluto notebook.) By default (e.g. in scripts or in the text REPL), it calls `show(io, "text/plain", x)`, or equivalently `show(io, MIME"text/plain"(), x)`, for an appropriate `io` stream. (In the REPL, `io` is an [`IOContext`](@ref) wrapper around [`stdout`](@ref).) The REPL uses `display` to output the result of an evaluated expression.
* The 3-argument [`show(io, ::MIME"text/plain", x)`](@ref) method performs verbose pretty-printing of `x`. By default (if no 3-argument method is defined for `typeof(x)`), it calls the 2-argument `show(io, x)`. It is called by the 2-argument `repr("text/plain", x)`. Other 3-argument `show` methods can be defined for additional MIME types as discussed above, to enable richer display of `x` in some interactive environments.
* The 2-argument [`show(io, x)`](@ref) is the default simple text representation of `x`. It is called by the 1-argument [`repr(x)`](@ref), and is typically the format you might employ to input `x` into Julia. The 1-argument `show(x)` calls `show(stdout, x)`.
* [`print(io, x)`](@ref) by default calls `show(io, x)`, but a few types have a distinct `print` format — most notably, when `x` is a string, `print` outputs the raw text whereas `show` outputs an escaped string enclosed in quotation marks. The 1-argument `print(x)` calls `print(stdout, x)`. `print` is also called by [`string(x)`](@ref).
* [`write(io, x)`](@ref), if it is defined (it generally has *no* default definition for new types), writes a "raw" binary representation of `x` to `io`, e.g. an `x::Int32` will be written as 4 bytes.

It is also helpful to be familiar with the metadata that can be attached to an `io` stream by an [`IOContext`](@ref) wrapper. For example, the REPL sets the `:limit => true` flag from `display` for an evaluated expression, in order to limit the output to fit in the terminal; you can query this flag with `get(io, :limit, false)`. And when displaying an object contained within, for example, a multi-column matrix, the `:compact => true` flag could be set, which you can query with `get(io, :compact, false)`.
Most new types should only need to define `show` methods, if anything,
since the other functions mentioned here (except `write`) call `show`
in the absence of a more specific method.

* [`show(io, x)`](@ref), with two arguments,
is the default simple text representation of `x`.
It is typically the format you would employ to input `x` into Julia.

* [`show(io, mime, x)`](@ref), with three arguments,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* [`show(io, mime, x)`](@ref), with three arguments,
* [`show(io, ::MIME"text/plain", x)`](@ref), with three arguments,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not understand why you want this bullet to be specific to a text representation rather than explaining the 3-argument show generally.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because text/plain is the common case, and most of this section is about text output . Most types don’t offer output for any other mime types, which is why they are only mentioned in passing here.

Also, if you want to overload it you need to know the specific signature.

performs verbose pretty-printing of `x`.
Multiple 3-argument `show` methods can be defined for various MIME types to enable
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Multiple 3-argument `show` methods can be defined for various MIME types to enable
Additional 3-argument `show` methods can be defined for other MIME types to enable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is contingent on the decision above: mime vs ::MIME"text/plain".

richer display of `x` in some interactive environments as discussed below.
By default (if no 3-argument method is defined for `typeof(x)`),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
By default (if no 3-argument method is defined for `typeof(x)`),
Although the underlying method is defined for a [`MIME`](@ref) argument, the caller can
simply pass a string such as `"text/plain"`, at the expense of a dynamic dispatch.
By default (if no 3-argument method is defined for `typeof(x)`),

Copy link
Contributor Author

@nathanrboyer nathanrboyer Jan 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is good to explain, but it leaves me with more questions than answers. Why is the string version used most places if it is slower?
See also this related issue I created: #56768

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Internally, we should call the MIME version. For users, the string version is easier, and is rarely performance-critical.

it calls the 2-argument `show(io, x)`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
it calls the 2-argument `show(io, x)`.
`show(io, "text/plain", x)` calls the 2-argument `show(io, x)`.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence is copied from the original text, but I am thinking now it can just be deleted?

If not deleted, then maybe moved into the display bullet like this?

In the REPL, display calls show(io, MIME"text/plain", x) (which defaults to show(io, x) if not separately defined).

Copy link
Member

@stevengj stevengj Jan 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s copied from the previous text, but you edited the preceding sentence so that the new qualification is needed.

I don’t think it can be deleted. It’s important to explain how 3-arg show defaults to 2-arg show (but only for text/plain)


* [`print(io, x)`](@ref) by default calls `show(io, x)`,
but a few types have a distinct `print` format —
most notably, when `x` is a string, `print` outputs the raw text
whereas `show` outputs an escaped string enclosed in quotation marks.
([`println`](@ref) and [`printstyled`](@ref) both call [`print`](@ref),
but add a newline or styling, respectively.)

* [`display(x)`](@ref) tells the current environment to display `x`
in whatever way it thinks best.
This is the function used by the REPL to output the result of an evaluated expression.
In the REPL, `display` calls `show(io, MIME"text/plain", x)`.
In a graphical environment, such as Jupyter or Pluto,
`display` might prefer a non-plaintext representation of an object
(such as HTML, Markdown, or a PNG or SVG image), if the corresponding 3-argument `show`
method is defined (as determined by [`showable`](@ref)).

* [`write(io, x)`](@ref), if it is defined
(it generally has *no* default definition for new types),
writes a "raw" binary representation of `x` to `io`,
e.g. an `x::Int32` will be written as 4 bytes.

The `io` argument for all the above functions is optional
and defaults to [`stdout`](@ref) if it is omitted;
this is the default output stream, typically a terminal window.
(`display` has no `io` argument
because the output format and stream/device is chosen by the display backend.)

More generally, `io` (of type [`IO`](@ref)) specifies a desired output stream
(such as a file, buffer, or pipe).
In the REPL, `io` is an [`IOContext`](@ref) wrapper around `stdout`, as described below.
It is also helpful to be familiar with the metadata that can be attached to an `io` stream
by an [`IOContext`](@ref) wrapper.
For example,
the REPL sets the `:limit => true` flag from `display` for an evaluated expression,
in order to limit the output to fit in the terminal;
you can query this flag with `get(io, :limit, false)`.
And when displaying an object contained within, for example, a multi-column matrix,
the `:compact => true` flag could be set,
which you can query with `get(io, :compact, false)`.

The functions `string`, `annotatedstring`, and `repr`
may be used to save values as a string (rather than output to `io`).
These functions call either `show` or `print` as indicated below,
so it is usually not necessary to define new methods for them separately.
(Note that [`convert(String, x)`](@ref) is not defined for most `x`
since the `convert` function is intended for implicit conversions.)

* [`string(x)`](@ref) and [`annotatedstring(x)`](@ref) call [`print(io, x)`](@ref).
* [`repr(x)`](@ref), with one argument, calls the 2-argument [`show(io, x)`](@ref).
* `repr("text/plain", x)`, with two arguments, calls the 3-argument [`show(io, ::MIME"text/plain", x)`](@ref).
nathanrboyer marked this conversation as resolved.
Show resolved Hide resolved

## "Value types"

Expand Down