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

proposed cleanup of output functions #7959

Closed
jiahao opened this issue Aug 11, 2014 · 24 comments
Closed

proposed cleanup of output functions #7959

jiahao opened this issue Aug 11, 2014 · 24 comments
Labels
domain:io Involving the I/O subsystem: libuv, read, write, etc. kind:julep Julia Enhancement Proposal
Milestone

Comments

@jiahao
Copy link
Member

jiahao commented Aug 11, 2014

A proposal to address #5709, #6493, #4117, #3932, and similar, discussed with @JeffBezanson and @stevengj today:

  1. Rename writemime(io, m::MIME, x) to write(io, m, x)
  2. Quasi-deprecate show in favor of write: have show(io, x) call write(io, MIME("text/plain"), x), and document overriding write as the preferred mechanism to customize output going forward. But don't actually deprecate show until Julia 0.5 or later to minimize package breakage. (Rationale: show is confusing because it sounds like display, but it behaves more like write.)
  3. Add parameters (properties) to MIME objects (show can then subsume showall, showcompact, etc with custom-specifiable precisions). For example, write(io, MIME"text/plain"(compact=true), x) instead of showcompact.
  4. Document a set of standard properties to control display of arrays (compactness), floating-point values (precision), etcetera.

As an implementation detail, we would want a fast way to represent MIME parameters as some kind of associative type in the MIME object. Perhaps a simple Associative{Symbol,V} type which uses linear search instead of a hash table. The same type could then be used for keyword arguments.

@jiahao jiahao added this to the 0.4-projects milestone Aug 11, 2014
@johnmyleswhite
Copy link
Member

+1

@IainNZ
Copy link
Member

IainNZ commented Aug 11, 2014

+100
What would print mean in this system?

@IainNZ
Copy link
Member

IainNZ commented Aug 11, 2014

Also, dump, how does that fit in?

julia> println(rand(2,2,2))
[0.8236910110089537 0.28537112769048023
 0.16443450746811683 0.5955359699883407]

[0.13911391896550862 0.007935274788062996
 0.6971448238297071 0.988148249124845]

julia> dump(rand(2,2,2))
Array(Float64,(2,2,2)) 2x2x2 Array{Float64,3}:
[:, :, 1] =
 0.50232   0.990722
 0.220421  0.50417

[:, :, 2] =
 0.103468  0.596584
 0.615835  0.552505

dump has better human-understandable output + readiblity than println, but also has that type information. println looks like its designed to let you be able to copy-paste it back into your code as a literal, but you can't because its >2D so its really just a mess for nothing.

@stevengj
Copy link
Member

  • print(io, x) would presumably call write(io, MIME"text/plain"(), x) (for the default non-compact output). (Probably it would call show for now, which would call write, for backward compatibility.)
  • display(d::TextDisplay, x) would call write(io, MIME"text/plain"(compact=true), x). (compact is just a placeholder; actual parameter names to be determined.)

I suppose we could have dump call write(io, MIME"text/plain"(dump=true), x), but I kind of think of dump as being a different thing altogether, almost a different MIME type (text/julia?).

@IainNZ
Copy link
Member

IainNZ commented Aug 11, 2014

So show = print?

@stevengj
Copy link
Member

Yes, I was thinking show(io, x) = write(io, MIME"text/plain"(), x), identical to print, and it eventually disappears altogether.

@IainNZ
Copy link
Member

IainNZ commented Aug 11, 2014

SGTM

@quinnj
Copy link
Member

quinnj commented Aug 11, 2014

Yeah, I think dump is going more the way of #6269 of looking automatically at the underlying structure and showing lots of low-level, development-focused information.

@JeffBezanson
Copy link
Sponsor Member

As long as we get rid of xdump (#4163) :)

It's possible one of the MIME parameters could be parseable, which attempts to print things in julia syntax. show and repr kind of do this now. Or we could try a "level of detail" system:

0 - just a brief summary (summary)
1 - pretty output, truncated
2 - pretty output, not truncated
3 - parseable, including all type info
4 - dump

@stevengj
Copy link
Member

A "level of detail" options seems fine to me for options that are mutually exclusive and can be reasonably ordered. We can define constants for these to make them more readable. (And we can always change it to a floating-point value if we want more resolution, which additionally gives us the option of detail=Inf.)

@JeffBezanson
Copy link
Sponsor Member

detail=Inf will print a hex dump of a core file of the process :)

@nalimilan
Copy link
Member

Would it make sense to distinguish real text/plain from a richer version supposed to be shown in terminals (colors, brightness...), say text/x-terminal? show would then default to it. At the moment, IIUC Base.have_color can be checked before printing color codes, but this does not make a difference between the terminal and a real ext file (in which color codes break the clean output).

@toivoh
Copy link
Contributor

toivoh commented Oct 15, 2014

Could we cater for nested indentation in the new system? To print nested
arrays, objects that contain objects, etc. AST printing already does this,
but in a specialized way.

@stevengj
Copy link
Member

I suppose we could have an indent keyword, but I'm concerned that it would easily get lost in indent-unaware writemime functions.

My feeling is that a more robust solution would be for array printing (etc.) to print sub-objects to a buffer, and then post-process the buffer to add indenting. We could add some helper functions for this.

@MikeInnes
Copy link
Member

What's the rationale for write(io, MIME"text/plain"(compact=true), x)? It looks to me like an overly-cute way of doing write(io, MIME"text/plain"(), x, Dict(:compact => true)).

For one thing, mime type and compactness seem like completely orthogonal concepts. The idea of a compact representation makes sense whether you're outputting to image or HTML or whatever, so why tie it to specific mime types?

If you don't care about binary representation and call a higher level method like display(x, Dict(:compact=>true)), the display system has to (1) choose a mime type, then (2) construct a MIME object with the given options embedded, rather than just passing through the options as a parameter. This obviously isn't technically difficult, but conceptually it seems a bit messy to me.

@MikeInnes
Copy link
Member

Also, if you want to be cute, how about using call overloading:

MIME"text/plain"(io, x)

@elextr
Copy link

elextr commented Jan 5, 2015

The use of MIME as a parametrised "format specification" object seems like a good one, it can be passed repeatedly without enumerating the args, but maybe it should have a different name to MIME?

@MikeInnes
Copy link
Member

#9633 is somewhat related.

@stevengj
Copy link
Member

stevengj commented Jan 6, 2015

MIME types are used to specify the format (compactness is part of the format), and MIME types can already carry options.

@MikeInnes
Copy link
Member

Compactness may be part of the format but it's not part of the mime type. The object you have there isn't a mime type, it's a formatting specification with a mime as a type parameter, Format{symbol("text/html")}(compact=true), that happens to be called MIME.

My issue is that this design forces the formatting specification to include a mime type. This makes sense for writemime, but it doesn't make sense for other functions like display. If I want to display(x) with the "compact" option, do I also have to choose a mime type? Or does display get its own, seperate formatting specification type, specific to that one function?

@hayd
Copy link
Member

hayd commented Mar 28, 2015

Is/should there be a mime type for writing to the terminal?

@JeffBezanson
Copy link
Sponsor Member

We use text/plain as the default, so there is always some mime type used for display even if you don't specify one or don't want to.

@hayd
Copy link
Member

hayd commented Mar 28, 2015

So this is in display? It's not clear how "topmost applicable" is decided (what your supposed to do to sneak something higher in their):

Display x using the topmost applicable display in the display stack, typically using the richest supported multimedia output for x, with plain-text STDOUT output as a fallback.

I see that markdown (for example), overrides Base.display to get this them to print in the terminal (with color/formatting), rather than using something like MIME"text/terminal".

@stevengj
Copy link
Member

Superseded by #14052

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:io Involving the I/O subsystem: libuv, read, write, etc. kind:julep Julia Enhancement Proposal
Projects
None yet
Development

No branches or pull requests