# Format conversion doesn't support padding

**URL:** <https://discuss.ocaml.org/t/format-conversion-doesnt-support-padding/10437>\
**Category:** Learning\
**Created:** [September 6, 2022, 12:54am UTC](https://discuss.ocaml.org/t/format-conversion-doesnt-support-padding/10437 "2022-09-06T00:54:17Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [September 6, 2022, 12:54am UTC](https://discuss.ocaml.org/t/format-conversion-doesnt-support-padding/10437/1 "2022-09-06T00:54:17Z")

</div>

E.g.

```auto
type number = Int of int | Float of float

let pp_number f = function
  | Int i -> Format.pp_print_int f i
  | Float fl -> Format.pp_print_float f fl

Format.printf "%20a\n" pp_number (Int 1)

```

Prints:

```auto
1

```

I.e. no padding. If I inspect the format string:

```auto
# format_of_string "%20a\n";;
- : (('_weak1 -> '_weak2 -> '_weak3) -> '_weak2 -> '_weak4, '_weak1, '_weak3,
     '_weak5, '_weak5, '_weak4)
    format6
=
CamlinternalFormatBasics.Format
 (CamlinternalFormatBasics.Alpha
   (CamlinternalFormatBasics.Char_literal ('\n',
     CamlinternalFormatBasics.End_of_format)),
 "%20a\n")

```

There is no padding instruction, as opposed to a format string with an int conversion which contains the padding instruction:

```auto
format_of_string "%20d\n";;
- : (int -> '_weak6, '_weak7, '_weak8, '_weak9, '_weak9, '_weak6) format6 =
CamlinternalFormatBasics.Format
 (CamlinternalFormatBasics.Int (CamlinternalFormatBasics.Int_d,
   CamlinternalFormatBasics.Lit_padding (CamlinternalFormatBasics.Right, 20),
   CamlinternalFormatBasics.No_precision,
   CamlinternalFormatBasics.Char_literal ('\n',
    CamlinternalFormatBasics.End_of_format)),
 "%20d\n")

```

Does anyone know why it doesn’t work for format conversions?

---

<div class="post-metadata">

**Author:** ![sim642](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/sim642/32/3597_2.png) [@sim642](https://discuss.ocaml.org/u/sim642)\
**Post date:** [September 6, 2022, 6:10am UTC](https://discuss.ocaml.org/t/format-conversion-doesnt-support-padding/10437/2 "2022-09-06T06:10:36Z")

</div>

The padding (and precision) there are part of the `Int` constructor (and some others) because their meaning is defined for values of those types:

> <https://github.com/ocaml/ocaml/blob/bb375e46fffa91b3152c8f75997c77e0df6b0f33/stdlib/camlinternalFormatBasics.ml#L379-L382>

For the `Alpha` constructor, which corresponds to `%a` in the format string and may delegate to _any_ printing code, it’s not defined how those should work:

> <https://github.com/ocaml/ocaml/blob/bb375e46fffa91b3152c8f75997c77e0df6b0f33/stdlib/camlinternalFormatBasics.ml#L425-L427>

The padding value outside on the `%a` would somehow have to propagate inside to the `%d` and apply there. Maybe padding could be implemented generically (not sure if it could or it has some type-specific behavior right now), but the same criticism would apply to flags and precision as well. Those certainly cannot work for arbitrary specifiers.

But indeed, I don’t see it documented, for which specifiers flags/padding/precision work and for which they silently don’t. That’s only apparent from looking at those internals.

---

<div class="post-metadata">

**Author:** ![gasche](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/gasche/32/4_2.png) [@gasche](https://discuss.ocaml.org/u/gasche)\
**Post date:** [September 6, 2022, 8:41am UTC](https://discuss.ocaml.org/t/format-conversion-doesnt-support-padding/10437/3 "2022-09-06T08:41:26Z")

</div>

Fun fact: there is a `-strict-formats` option that rejects many invalid formats instead of silently doing something.

```auto
ocaml -strict-formats
# Printf.printf "%20a" (fun _ -> print_int) 42;;
Error: invalid format "%20a": at character number 0,
`padding' is incompatible with 'a' in sub-format "%20a"

```

Benoît Vaugon and myself implemented this when we rewrote formatting support to use GADTs (Benoît’s idea). It was not enabled by default because various programs in the wild would have started failing (they contained invalid but innocuous formats and just worked), and we wanted excellent compatibility by default to sell the (large) change. Ideally this could be turned into a warning, but we never got around to doing this work. Volunteers welcome 🙂 (Adding warnings is not a magic bullet because if you enable them by default, and people set errors on warnings, then you are back to breaking code again.)

---

<div class="post-metadata">

**Author:** ![sim642](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/sim642/32/3597_2.png) [@sim642](https://discuss.ocaml.org/u/sim642)\
**Post date:** [September 8, 2022, 8:18pm UTC](https://discuss.ocaml.org/t/format-conversion-doesnt-support-padding/10437/4 "2022-09-08T20:18:23Z")

</div>

> [@gasche](#):
>
> It was not enabled by default because various programs in the wild would have started failing (they contained invalid but innocuous formats and just worked), and we wanted excellent compatibility by default to sell the (large) change.

Out of curiosity I had a look and discovered that both its documentation and implementation actually promise to remove the non-strict behavior altogether:

> <https://github.com/ocaml/ocaml/blob/949e2626c22b5fe8159cb29d47207d5621eabf90/manual/src/cmds/unified-options.etex#L691-L694>

> <https://github.com/ocaml/ocaml/blob/cce52acc7c7903e92078e9fe40745e11a1b944f0/stdlib/camlinternalFormat.mli#L75-L80>

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [September 9, 2022, 2:21am UTC](https://discuss.ocaml.org/t/format-conversion-doesnt-support-padding/10437/5 "2022-09-09T02:21:14Z")

</div>

Then it seems OCaml 5 is the perfect time to turn this on.

---

<div class="post-metadata">

**Author:** ![sim642](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/sim642/32/3597_2.png) [@sim642](https://discuss.ocaml.org/u/sim642)\
**Post date:** [September 10, 2022, 4:20pm UTC](https://discuss.ocaml.org/t/format-conversion-doesnt-support-padding/10437/6 "2022-09-10T16:20:41Z")

</div>

Indeed, I opened an issue to bring attention to it: [`-strict-formats` by default · Issue #11538 · ocaml/ocaml · GitHub](https://github.com/ocaml/ocaml/issues/11538).
