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

"Lowering" types before rendering via writemime #9633

Closed
MikeInnes opened this issue Jan 6, 2015 · 4 comments
Closed

"Lowering" types before rendering via writemime #9633

MikeInnes opened this issue Jan 6, 2015 · 4 comments
Labels
julep Julia Enhancement Proposal

Comments

@MikeInnes
Copy link
Member

The current writemime method of rendering types for display forces one to write a method for each mime type M, for each displayable type T – which is a lot of definitions if you want to support a wide range of displays.

To me this is a red flag for lack of abstraction; a table is a table is a table regardless of whether it's rendered in HTML, the terminal, as an image, whatever, so you shouldn't have to write table-lowering code T×M times. Instead I want to be able to write:

lower(d::DataFrame) =
  Header("DataFrame", Table(...))

lower(m::Matrix) =
   Header("$(eltype(m)) Matrix", Table(m))

The Header and Table types would provide the writemime methods for you, so that the one definition gets you display on every device.

Equally, you could (for example) take advantage of a library like Markdown.jl for rich formatting:

lower(m::Type) = md"$(parent(m)).**$m**"

which would tell Julia to print the type DataFrame as "DataFrames.DataFrame" where possible (e.g. terminal, IJulia) and fall back on plain text everywhere else (assuming I didn't just make up the parent function). This is very similar to what I'm doing already in Juno, and it works nicely.

I'm not certain how best to implement this yet. My rough idea is to have a writemime fallback that looks like:

writemime(io::IO, m::MIME, x) = writemime(io, m, applylower(x))

where applylower applies the lower function until x stops changing. If there's no lower method for x, you get a method error, since there's no other way to display it.

This complicates things slightly for fallback methods (e.g. all types can write to text/plain by default) which override this method, since they'll have to call applylower explicitly. Since there aren't many of those, though, it's perhaps not a big problem.

I suspect there might be a more elegant design to be had here, so I'm open to suggestions.

@MikeInnes MikeInnes added the julep Julia Enhancement Proposal label Jan 6, 2015
@stevengj
Copy link
Member

stevengj commented Jan 6, 2015

I'm confused. If you have a type T, you only implement one writemime method per MIME type you want to output, not per display.

@MikeInnes
Copy link
Member Author

Sure, I'm not saying otherwise. But different displays support different mime outputs in general, so if you want to support a range of displays you will have to implement a range of writemime methods.

(If it's more precise, replace "displays" with "output formats". The point stands)

@MikeInnes
Copy link
Member Author

It would actually be sufficient to be able to overload

writemime(io::IO, m, f::Foo) = writemime(io, m, Table(...))

which has the advantage that it doesn't introduce a new function. However, it's ambiguous with any fallback methods. Not sure if there's a good way around that.

@MikeInnes
Copy link
Member Author

Now I think about it, the applyrender method above would also cause problems for fallbacks for abstract types. Again though, maybe that could be ignored, since (a) there aren't many and (b) you're less likely to want to override them anyway.

Another way to go might be to have a separate writemime_fallback(io, m, x) function which is called if no other writemime method is applicable. In general it would be the same as it is now, but fallback methods would overload writemime_fallback instead of writemime to avoid clashes and allow for lowering.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
julep Julia Enhancement Proposal
Projects
None yet
Development

No branches or pull requests

2 participants