# Which pretty-printer library is recommended for new code?

**URL:** <https://discuss.ocaml.org/t/which-pretty-printer-library-is-recommended-for-new-code/2973>\
**Category:** Ecosystem\
**Created:** [November 28, 2018, 4:28pm UTC](https://discuss.ocaml.org/t/which-pretty-printer-library-is-recommended-for-new-code/2973 "2018-11-28T16:28:11Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![MattWindsor91](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mattwindsor91/32/1327_2.png) [@MattWindsor91](https://discuss.ocaml.org/u/MattWindsor91)\
**Post date:** [November 28, 2018, 4:28pm UTC](https://discuss.ocaml.org/t/which-pretty-printer-library-is-recommended-for-new-code/2973/1 "2018-11-28T16:28:11Z")

</div>

(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.

---

<div class="post-metadata">

**Author:** ![c-cube](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/c-cube/32/1727_2.png) [@c-cube](https://discuss.ocaml.org/u/c-cube)\
**Post date:** [November 28, 2018, 5:11pm UTC](https://discuss.ocaml.org/t/which-pretty-printer-library-is-recommended-for-new-code/2973/2 "2018-11-28T17:11:21Z")

</div>

`Format` is perfectly adequate for most pretty-printing. I’d suggest using [fmt](http://erratique.ch/software/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.

---

<div class="post-metadata">

**Author:** ![lindig](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/lindig/32/532_2.png) [@lindig](https://discuss.ocaml.org/u/lindig)\
**Post date:** [November 28, 2018, 5:15pm UTC](https://discuss.ocaml.org/t/which-pretty-printer-library-is-recommended-for-new-code/2973/3 "2018-11-28T17:15:32Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Drup](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/drup/32/35_2.png) [@Drup](https://discuss.ocaml.org/u/Drup)\
**Post date:** [November 28, 2018, 5:25pm UTC](https://discuss.ocaml.org/t/which-pretty-printer-library-is-recommended-for-new-code/2973/4 "2018-11-28T17:25:05Z")

</div>

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](http://erratique.ch/software/fmt), [`CCFormat`](https://cedeela.fr/format-all-the-data-structures.html) or, apparently, base. `fmt` can also handle colors.

---

<div class="post-metadata">

**Author:** ![c-cube](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/c-cube/32/1727_2.png) [@c-cube](https://discuss.ocaml.org/u/c-cube)\
**Post date:** [November 28, 2018, 5:34pm UTC](https://discuss.ocaml.org/t/which-pretty-printer-library-is-recommended-for-new-code/2973/5 "2018-11-28T17:34:48Z")

</div>

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 😉

---

<div class="post-metadata">

**Author:** ![mjambon](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mjambon/32/6180_2.png) [@mjambon](https://discuss.ocaml.org/u/mjambon)\
**Post date:** [November 28, 2018, 6:47pm UTC](https://discuss.ocaml.org/t/which-pretty-printer-library-is-recommended-for-new-code/2973/6 "2018-11-28T18:47:00Z")

</div>

You should consider [easy-format](https://github.com/mjambon/easy-format) as well.

---

<div class="post-metadata">

**Author:** ![n4323](https://avatars.discourse-cdn.com/v4/letter/n/97f17d/32.png) [@n4323](https://discuss.ocaml.org/u/n4323)\
**Post date:** [November 29, 2018, 10:32am UTC](https://discuss.ocaml.org/t/which-pretty-printer-library-is-recommended-for-new-code/2973/7 "2018-11-29T10:32:34Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![c-cube](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/c-cube/32/1727_2.png) [@c-cube](https://discuss.ocaml.org/u/c-cube)\
**Post date:** [November 29, 2018, 3:00pm UTC](https://discuss.ocaml.org/t/which-pretty-printer-library-is-recommended-for-new-code/2973/8 "2018-11-29T15:00:58Z")

</div>

You might want to look at [https://github.com/c-cube/zipperposition](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 @}”).

---

<div class="post-metadata">

**Author:** ![MattWindsor91](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mattwindsor91/32/1327_2.png) [@MattWindsor91](https://discuss.ocaml.org/u/MattWindsor91)\
**Post date:** [December 5, 2018, 12:04pm UTC](https://discuss.ocaml.org/t/which-pretty-printer-library-is-recommended-for-new-code/2973/9 "2018-12-05T12:04:47Z")

</div>

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 🙂

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

---

<div class="post-metadata">

**Author:** ![Yaron\_Minsky](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yaron_minsky/32/11_2.png) [@Yaron\_Minsky](https://discuss.ocaml.org/u/Yaron_Minsky)\
**Post date:** [December 5, 2018, 1:58pm UTC](https://discuss.ocaml.org/t/which-pretty-printer-library-is-recommended-for-new-code/2973/10 "2018-12-05T13:58:08Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![MattWindsor91](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mattwindsor91/32/1327_2.png) [@MattWindsor91](https://discuss.ocaml.org/u/MattWindsor91)\
**Post date:** [December 5, 2018, 3:56pm UTC](https://discuss.ocaml.org/t/which-pretty-printer-library-is-recommended-for-new-code/2973/11 "2018-12-05T15:56:23Z")

</div>

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 🙂
