Type indentation vs match indentation

When discussing ocamlformat configs with some people, one interesting point came out. The vast majority of existing OCaml code is formatted using type_indent = 2 and match_indent = 0 ( using ocamlformat terminology):

type t = 
  | A
  | B

match x with
| A -> ...
| B -> ...

Is there good justification for this (other that it has been the default for ocp-indent and now ocamlformat too)? Wouldn’t it been more consistent to use match_indent = 2, e.g.

match x with
  | A -> ...
  | B -> ...

One argument I can think of is that matching without the first optional vertical bar looks nicer this way:

match x with
  A -> ...
| B -> ...

But you can also do the same for type definitions as well

type t = 
  A
| B

To see my personal justification, let’s expand the dots in your match example:

match x with
| A ->
  let aux = f x in
  ...
  foo
| B ->
  bar;
  baz

As you can see, what you might call the “body” of a match branch is typically indented by another 2 spaces. If you were to indent the “head” of the match branch by 2 spaces, you would end up with a total indentation of 4 spaces:

match x with
  | A ->
    let aux = f x in
    ...
    foo
  | B ->
    bar;
    baz

This is not a very econnomical use of white space, and with nested matches you quickly run out of space. Moreover, one may argue that you’re double indenting match cases: once for the head, and once for the body.

I’ll throw this out there just in case: indentation is about the positioning of text. Punctuation symbols are here to satisfy the syntax but they’re repetitive and mostly ignored by the reader. It’s good to pretend they’re not even here, and see if the layout of the blocks of text makes sense.

For this example, this gives us:

match x with
| A ->
    let aux = f x in
    ...
    foo
| B ->
    bar;
    baz

because my brain and many other people’s brain perceive it as:

match x
  A
    let aux = f x
    ...
    foo
  B
    bar
    baz

That’s a good point. But following this argument shouldn’t type declarations be treated the same?

type t = 
| A
| B

and ignoring the vertical bars we have:

type t =
  A
  B

I don’t disagree. It’s not as bad as having zero indentation, though. The following would be hard to read:

type t =
A
B

but the following would already be better:

type t =
 A
 B

or

type t =
     A
     B