As far as I can tell, the complaint is maybe that ocaml doesn't have something exactly like C#/Java interfaces (which I think is a fair assessment). So maybe the author is lamenting that they can't just rewrite their java code in every language?
Although, they also mention rust traits. Which at first blush look very similar to c#/java interfaces (at least closer than anything ocaml has). However, at least in my experience, rust traits don't quite fulfill the same niche as c#/java interfaces because rust cares a lot about when you can figure out the size of your objects. So every time I tried to use them like I would a C# interface, I wound up regretting the decision.
Ultimately, this article feels like a superficial "I don't like ocaml" blurb. There is a lot to be warry of with respect to ocaml. Although, the fact that ocaml still exists as a niche language with a lot of very significant maintenance and active development (effects + multithread recently landed), shows that the author did not pay sufficient attention.
Anyway, what they're referring to has been rehashed a billion times already in the relevant communities. ML functors being good has little to do with it; even with functors and modules, you're required to actually pass them around and construct them explicitly and use it at call sites. If you want a Set for Strings, you make an instance of the Set functor with the proper implementation of the signature which specifies the Set ordering (or whatever, assuming that's the signature needed), but then you still have to use the functor explicitly and pass it around. You can have more than one, for good reason, so making this explicit usage implicit is tricky. In contrast, in Haskell, there is one ordering for each (nominal) type, so there is no need to refer to specific instance of `Set String` or whatever to define the ordering. `Set` uses `Ord`, which has an unambiguous implementation. It is resolved implicitly for you.
A lot of people just call this an "interface." Hell, even I do that. It's just a generalized term for "ad hoc polymorphism" where you don't need to guide instance resolution, I guess.
The author even quite literally (in like, the next sentence) says that modular implicits would help this issue -- it would allow many uses of an instantiated module to become more implicit (e.g. uses of something like "turn this thing into a string for debugging" without having a menagerie of individual string_to_ functions). But they are not yet upstream. Even then, implicits have their own tradeoffs, and the design spectrum here has no clear winner. Even Haskell has adopted Backpack, which takes a different spin on the whole thing using mixin-modules (no functors), but tries to keep the characteristic power of functors available in a languages where typeclasses reign.
Much of this is also relevant in the design of theorem proving communities, e.g. Lean4, which heavily relies on implicit instance resolution in a similar form to modular implicits; yet it doesn't have modules in the ML sense. They really want this approach though, because in math you really do have lots of instances you might refer to by name. But in programming it's not always the same; implicit resolution of ad hoc instances is often very useful.
It's not really a weird or unusual complaint, it's been rehashed to death, but maybe it could be less ambiguous.
For example, you can do OOP-like interfaces/abstract classes with `class virtual`, but classes and modules don't mix together nicely. Your virtual class cannot abstract over modules, nor do functors abstract over classes.
So you end up either using modules/functors pervasively, or using objects pervasively. It's like there's two separate languages competing for use.
Using modules seems to be more common, but it overshadows some features of OCaml's object system which are pretty unique to it and useful: row polymorphism and functional objects.
Obviously, functors have a clear performance advantage because they're expanded at compile time, and objects have the vtable overhead.
I think it would be interesting to see a variant of OCaml which goes all-in on the object side of things. Strip away the modules and functors and a provide standard library based around functional objects.
BUT ocaml also has row polymorphism and polymorphic invariants, which you can use to get something much directly closer to c#/java interfaces. The major difference is that with ocaml it's structural typing and with c#/java it's nominal typing. However, at a high level you can write the code in a very similar structural pattern as with what you get in c#/java.
Clearly not considering he mentions typeclass in the article.
Module signatures are similar to interface and parametrized modules allow you to do what you would do with abstract class: you define a signature and then write a module using these functions. Parametrized modules are more or less a generalization of functions which goes from module to module.
Pretty weird way to start the post.