We've been going back and forth for a while on where we should be using .mli files are where they are unnecessary. I've now asked a couple of questions related to this on OCaml discuss here and here and wanted to summarize my understanding and get some consensus on this.
The first question I asked was about why Jane Street use three files [X].ml, [X].mli and [X]_intf.mli in their libraries. The answer is basically that it saves repeating, and therefore having to update, signatures in two places. The approach is only needed when a module exposes a functor.
My second question was to clarify why you would use an interface file in three situations. The easy cases are:
- When you want to hide the implementation you clearly need to use one.
- When a file only exposes a module signature you do not need one.
The third case is where we have an implementation file but the interface doesn't hide anything. The response to my questions suggested that this is indeed discretionary but recommended avoiding using module type of which we do in a number of places at the moment. Another respondent suggested that .mli files are usually added when a module is matured and the Jane Street style guide recommends putting your docs in the .mli.
The final feedback was that there is no need to include 'index modules' like Common.ml or Middle.ml since dune generates this for you. This is true even in cases where you don't want to expose all the modules in the library since this can be handled using dunes private_modules stanza.
I asked about the impact of .mli on compilation times but this wasn't mentioned a pro/con by any respondents.
Based on this, my instinct is to:
- Move to the Jane Street style of
[X].ml, [X].mli and [X]_intf.mli for modules exposing functors
- Remove usage of
module type of
- Remove 'index modules' (which should mostly take care of point 2).
- Start to create .mli where the implementation is more settled and being to add docs there.
This would save us a few files (with point 3) but cost us a few with point 1. However, adopting 1 will help with maintenance.
@rybern @seantalts @VMatthijs I'd like to get your thoughts on this before making any changes.
We've been going back and forth for a while on where we should be using .mli files are where they are unnecessary. I've now asked a couple of questions related to this on OCaml discuss here and here and wanted to summarize my understanding and get some consensus on this.
The first question I asked was about why Jane Street use three files
[X].ml,[X].mliand[X]_intf.mliin their libraries. The answer is basically that it saves repeating, and therefore having to update, signatures in two places. The approach is only needed when a module exposes a functor.My second question was to clarify why you would use an interface file in three situations. The easy cases are:
The third case is where we have an implementation file but the interface doesn't hide anything. The response to my questions suggested that this is indeed discretionary but recommended avoiding using
module type ofwhich we do in a number of places at the moment. Another respondent suggested that .mli files are usually added when a module is matured and the Jane Street style guide recommends putting your docs in the .mli.The final feedback was that there is no need to include 'index modules' like
Common.mlorMiddle.mlsince dune generates this for you. This is true even in cases where you don't want to expose all the modules in the library since this can be handled using dunesprivate_modulesstanza.I asked about the impact of .mli on compilation times but this wasn't mentioned a pro/con by any respondents.
Based on this, my instinct is to:
[X].ml,[X].mliand[X]_intf.mlifor modules exposing functorsmodule type ofThis would save us a few files (with point 3) but cost us a few with point 1. However, adopting 1 will help with maintenance.
@rybern @seantalts @VMatthijs I'd like to get your thoughts on this before making any changes.