Format vs PPrint in practice?

Hi, I am evaluating the two pretty printers from practical point of view, I am glad to hear what you think.

  • Expressivity
    It seems that in pprint, it is hard to express vbox unless you use hardline exclusively. Is there anything that is easy to express in PPrint but hard to express in Format?
  • Performance
    In theory, Format should be faster than PPrint and more memory efficient, but Format did lots of things which are not needed in pretty printers, e.g, the format string trick using GADT. I had an impression that Format had a very large constant factor, so in practice, it is hard to tell which one is faster?
  • Hackability
    It seems pprint is pretty small so it is trivial to maintain your own version but Format is too big and coupled with the compiler so it is hard to change how it works internally

I noticed that ocamlformat used Format, did they evaluate PPrint as well?
Let me know if my conclusion is incorrect, thank you! – Hongbo

1 Like

ocamlformat does use format, but pprint would be better.

The main reason for that is the ifflat combinator, that is possible to simulate in format, but only with backtracking. This makes pprint a lot better (and faster) if you need to format stuff differentely on one line or multiple, and that is the case in ocamlformat.

Also I just like pprint a lot better, because everything is named

1 Like

I did not carefully evaluate PPrint and other alternatives when initially writing ocamlformat. I was concerned about performance, of backtracking in particular. In Format there are only very limited forms of backtracking, and can then be implemented with a polynomial algorithm. At the beginning I under-appreciated the need for backtracking, and eventually ocamlformat ended up rerunning the entire format pass potentially several times to work around the limited form of backtracking supported.

Note that if you just don’t use format strings, any performance worries there can be avoided. That said, I don’t expect the GADT implementation to be slow. Also be aware that a lot of anecdotal experience with Format being very slow seems to be from when it is used to repeatedly create strings with asprintf and then concat them, so not Format’s fault.

For a new project, I would advise to carefully consider the situations where you want different output, nesting, or breaking behavior depending on whether or not the result fits within the margin. Then prototype those forms of backtracking with the alternatives and see if they work well enough.

Regarding hackability, while I won’t claim that it is simple code, ocamlformat does vendor a copy of Format that includes some changes relative to the stdlib. So it is possible.