OCaml-like modules using untyped languages

When reading Les Accepteurs : Un nouveau modèle de programmation i realized this tiny untyped language can actually mimic OCaml modules :

set-make (Compare) =>

(  nil ->
     (  size => 0
     || add(Item) => set(nil,Item,nil)
     || member(Item) => false
     )

|| set(Left,Pivot,Right) ->
     (  size =>
          Left size + 1 + Right size
     || add(Item) =>
          (  less  => set(Left add(Item),Pivot,Right)
          || more  => set(Left,Pivot,Right add(Item))
          || equal => ∆ )
          (  Compare Item Pivot  )
     || member(Item) =>
          (  less => Left  member(Item)
          || more => Right member(Item)
          || equal => true )
          (  Compare Item Pivot  )
     )
)

Do you consider this common practice or special ?
(i am not fluent enough in Scheme and alike to answer myself)

1 Like

I don’t see it as being particularly special. Lots of languages have a similar mechanism for generic programming which almost always boils down to “dictionary passing” (e.g. dependency injection in Java or typeclasses in Haskell) or static specialisation (e.g. monomorphisation, as in C++ templates, or “defunctorisation” in the MLton compiler for SML modules).

The primary benefit, as I understand it, of the OCaml module system - compared to SML’s - is the support for separate compilation (thanks to manifest types in signatures). So, you have an expressive module typing discipline - conducive to separate compilation - that is effectively describing how you can manipulate dictionaries (as functors do actually compile to functions between records). So, despite the fact you can somewhat emulate the important generic programming aspects of modules, it’s the safety of composition - at scale - that makes them effective. Personally, I have no interest in trying to engineer large software without a static typing discipline.

If you are interested in OCaml’s module system, there’s lots of insightful papers about the ideas, particularly Manifest types, modules, and separate compilation and Modular Modules.

4 Likes

I think separate compilation of first-order modules is also something possible with SML modules, and that compilers like the ML Kit do this. The abstract of (this paper)[https://elsman.com/mlkit/pdf/icfp99.pdf] seems to indicate as much.

The main benefit (as I see it) of OCaml modules over SML modules is that OCaml supports higher order modules. SML/NJ also does but most SML compilers don’t as it isn’t a feature mentioned in the Definition.

1 Like

I don’t think SML has any specific carve-outs for separate compilation, so this is compiler-specific. And tools like MLton go out of their way to support whole-program optimization, which essentially precludes separate compilation.

Conversely, OCaml bakes this in as a hard requirement (possibly to a fault, depending on how you want to compile/link). One issue, in particular, is that this means you can’t monomorphize; separate compilation essentially means that you have to have uniform runtime representation (at least in OCaml’s current runtime). On the other hand, this uniformity makes it seamless to use higher order modules. Also the choice of using generative or applicative functors may be unique to OCaml (but don’t quote me on that). I’m not sure how/if that ties into separate compilation per se, but uniform representation can’t hurt.

2 Likes