[ANN] OCamlformat 0.14.0

This upgrade is likely to generate a huge diff on projects that use the default profile, so I would like to expand a bit on the reason.

According to the syntax rules used by the ocaml tools (the ocaml compilers, ocamldoc, odoc), it is always possible to put the doc-comment before an item.

Some teams prefer to put the documentation after. But that is not always possible. For example, type t = A | B (** doc *) will attach the doc-comment to B, not to t. The only way to attach the comment to t is by putting the comment before.

Enter ocamlformat: doc-comment placement is controlled by an option with two values, before or after. before will always place the comment before. after determines if it is possible to put the comment after, and if it is not, will put it before.

Some items cannot have comments after, like variant types (as described above). But there is another reason not to put comments after. In some cases, that can put the comment far from the thing it is documenting. Considering modules, the following is nice:

module M = L.M
(** doc *)

But this is not great is the structure is large:

module M = struct
  ...
  ...
end
(** doc *)

To summarize, when ocamlformat is configured to put comments after, it has to follow a complex heuristic to determine whether it has to fallback to before. In the case of a module, it depends on its shape, how many functor arguments are there, this kind of things (for various reasons, we don’t know how large something is going to be in advance, so we have to look at its shape). The point is that it is complicated to understand and explain, and that fixing it always makes it more complex. Another aspect is that in the end, we want ocamlformat to be pretty stable when it reaches 1.0.0, and complex rules are at odds with this goal.

So, we have decided to simplify the rule: instead of looking deep in the AST, we just look at the kind of item this is. For val and external items, it is always possible to put the doc-comment after, so we follow exactly what the configuration option says.

As a user of the default profile, what this means for you: for items that are not val or external, and considered “simple” by the 0.13.0 heuristic, doc-comments are going to move from after to before.

Based on these reasons, you will understand that before is always simpler. You can opt into this by setting doc-comments-val=before. This will cause an even larger diff as all items are going to move before (that is: all items described just above, plus val and external items), but the rule gets extremely simple (everything is put before). It is possible that this option will become the default in the future, but we have not decided this yet (in this case, if you did not opt into it, you will see comments on val and external items move at that time).

3 Likes