Which pretty-printer library is recommended for new code?


#1

(Apologies if this is in the wrong place—am new here! Hi!)

I’ve recently just picked up OCaml after a few years of working with F#. So far, I’ve mainly been using the standard library’s Format module to do pretty-printing (so, boxes and boxes and more boxes).

As I’m gravitating towards the core/core_kernel/base trifecta, I’ve noticed that base has deprecated Format (but not Format.formatter itself, which survives as Formatter.t I think). This makes me wonder—is Format considered obsolete in some sense, and, if so, is there a better pretty-printer library that I should be using instead?

I’ve seen quite a few pretty-printers, but none of them seem to be objectively better than Format, hence the confusion (that, and Base doesn’t mention why it’s deprecated the stdlib version!).

In case of XY problems: I’m wanting to pretty-print a variety of things: bits of programming language, error messages, warnings, tables (eg, ASCII representations thereof), and the occasional debug output (though I usually use sexps for this). I’d like to use colour on the terminal if possible (maybe with a degree of decoupling between semantics and output like Format seems to have), but I’m not yet doing so.


#2

Format is perfectly adequate for most pretty-printing. I’d suggest using fmt or some similar module, to get a nice set of combinators for printing lists and adding colors. It should compose with most other things with the %a directive to use custom printers.


#3

Pretty printers in the tradition of Format are not the right tool for emitting tables, I believe. Format is designed to turn a tree structure into a sequence of indented lines which is not the same as box structure where boxes can be stacked and concatenated.


#4

One must distinguish two aspects: the type Format.formatter and the printf family of functions on one side, and the concrete Format API on the other.

Format.formatter is very much not deprecated, and is very used through many libraries. The Format API is universally considered quite terrible, and is better avoided.

Fortunately, there are many alternative libraries that provide better APIs, such as fmt, CCFormat or, apparently, base. fmt can also handle colors.


#5

For tables I think the only realistic option is to pre-render them using some specialized library and then print them into the formatter?

@Drup CCFormat also handles colors, btw, including nested color boxes :wink:


#6

You should consider easy-format as well.


#7

What’s a good example to see CCFormat in action?


#8

You might want to look at https://github.com/c-cube/zipperposition and
grep -C3 CCFormat -r src to see all its uses (sometimes it’s aliased
as Fmt, too). It’s mostly basic usage of the module, I also use colors
(stuff like “@{ blablabla @}”).


#9

Thanks for the replies!

I’ve decided to give fmt a try, mostly just because it seems to sit alongside Core nicely (it doesn’t depend on much, and Core is already pulling in a lot of metal). So far it seems to be a nicer, compositional interface compared to Format, and it makes a lot of the little utility functions I wrote along the way obsolete :slight_smile:

That said, I might have a look at containers/CCFormat at some point down the road too.


#10

A side note, but if you’re concerned about the weight of Core, you might want to give Base a try.


#11

Of course, thanks!

I didn’t mean to imply that Core being large was a concern—the thing I’m working on uses a fair amount of Core-specific (and in some places even Core_extended-specific!) modules and functions—just that since I already have a big, broad library in my deps that does almost everything I need, I’d rather not pull in too much else :slight_smile: