nim-lang / RFCs

A repository for your Nim proposals.
137 stars 23 forks source link

std/prettyprints: pretty print any expression (including with cycles), customizable #385

Open timotheecour opened 3 years ago

timotheecour commented 3 years ago

proposal

add a std/prettyprints module to allow pretty printing arbitrary expressions

design goal

As with std/jsonutils this should have:

unlike dollars.nim, this is not a low-level module, and can have (at least optionally) heaver dependencies (eg tables.nim) for needed functionality and to simplify implementation

eg:

type Option = ref object
  depth: int # how far to recurse
  showDistinct: bool # when true, if no `$` overload exists for a distinct type, print via undistinct
  fpFormat: string # customizes FP printing eg `"%.02f"`
  # etc... that customizes prettyprinting

pretty[T](result: var string, a: T, options: Options = nil) = ...
template pretty[T](a: T, options: Options = nil): string = pretty(result, a, options)
  # for convenience since so common

all overloads are outplace form and there's a single inplace form, just like in https://github.com/nim-lang/RFCs/issues/191

I've already implemented that in a private project with extensive options, so I know it's quite doable.

sample output

links

konsumlamm commented 3 years ago

This looks like a cool idea, but I don't see why it should be in the standard library. I think it would fit better as a nimble package (or at least in dist/stdx).

Clyybber commented 3 years ago

It exists as a package already; https://github.com/treeform/print, I don't think absorbing/obsoleting packages into the stdlib is healthy for the ecosystem at whole. We should simply ship a bunch of packages with the installation to give them exposure and use.

zetashift commented 3 years ago

It exists as a package already; https://github.com/treeform/print, I don't think absorbing/obsoleting packages into the stdlib is healthy for the ecosystem at whole. We should simply ship a bunch of packages with the installation to give them exposure and use.

treeform/print could be a great addition to fusion?

haxscramper commented 3 years ago

I don't think it is a good idea to select any single implementation and add it to the fusion or stdlib, because there are so many elements that can be done differently, it would be quite hard to implement them all and have a reasonably simple solution. I also have a pretty-printer library that supports gitignore-style globs to ignore part of the objects, and global layout optimization - depending on the size of the object it might print it differently. I also plan to add support for int/string print style configuration (using gitignore globs as selectors as well), so I could select to print **/bitFlags in binary representation.

Do these features sound like something one might need? Yes, absolutely. I don't want to stare at the screen-worth of sequences, and for different reasons I do print a lot of them, so I put extra effort to layout things as compact as possible, but make it easier to view. In order to provide good layout, I implemented ad-hoc layouter for the first version and now writing v2 that would use https://research.google/pubs/pub44667/. Others might have different use cases, personal preferences, and in their case it might be completely pointless to put so much effort into this.

For example, to me, it is kind of important that would be able to print things like let val = mapIt(0 .. 20, mapIt(1 .. sample({0 .. 5}), (it, $it))) nicely (this is a synthetic example, but close enough to some things I'm working with). But it seems like this is not the case for treeform/print:

image

zetashift commented 3 years ago

@haxscramper I see, your prettyprint library does look great!

I don't think it is a good idea to select any single implementation and add it to the fusion or stdlib, because there are so many elements that can be done differently

This is true, but there seems to be a need for easy pretty printing out there, so it might be worth discussing adding one of them to fusion, I don't see them necessarily being needed in a stdlib. I think this is one of those cases, adding one of them to fusion can be useful.

lypanov commented 3 years ago

As a nim-newbie leveling up it's extremely unexpected that httpclient's Response isn't echo'able. treeform/print works well enough. But I agree with the sentiments from the OP. I really would expect such functionality to be in the standard library. I do OTOH agree completely that it should be kept as minimal as possible and avoid external large dependencies. Alas at my experience level I can't help with solving that issue.

haxscramper commented 3 years ago

We can add something like treeform/pprint to the fusion. Full-featured pretty print implementation is very complicated, so I don't think like haxscramper/hmisc/pprint would be accepted anyway, and for simple use cases it is usually enough. Add some heuristics here and there to make sure long sequences/tables look good etc, and control whether output is colored or not

This partially contradicts what I said earlier, but in the end treeform/print would be enough for the most, so I think it would be better to settle on an existing simple implementation rather than trying to discuss all potential requirements. But this would mean some things like HTML output should be left out.