As a former OCaml hobbyist programmer my take on these kind of books or articles is that, yes OCaml is extremely elegant and beautiful as a programming language and it shines for simple applications. Some parts of it are actually not so elegant, for example the object oriented aspect completely spoil the elegance of the core language.
On the other side OCaml, as a pure functional programming language with immutable value by default doesn't scale well to large, complex application. Just the paradigm is no longer tenable and you need to switch at least partially to imperative programming with mutable variable. For example this is what it does the implementation of the OCaml itself.
To develop further the point about "what doesn't scale" there is also the function with unnamed arguments and currying. While extremely elegant for simple programs it gets confusing for real-world applications when function needs quite a lot of arguments and there is no longer any obvious order to give them. If you stick with that and you choose an order it becomes arbitrary, difficult to remember and currying no longer makes a lot of sense.
Functional programming with immutable values is a wrong pattern for programming languages. Many algorithms, almost all actually, are naturally expressed in imperative style with mutable arrays or variables.
What is needed is to bridge the good things from OCaml, the type system, the pattern matching with tagged types into a modern, imperative programming languages.
Rust is a sort of answer but they got it wrong because it is too low level about managing the memory, the ownership pardon, and everything else so programmers cannot just express the algorithm or the logic they want to implement but they have to spend a lot of mental energy thinking about ownership issues and unneeded accidental complexity like lifetime annotations.
> To develop further the point about "what doesn't scale" there is also the function with unnamed arguments and currying.
Not sure what you mean by unnamed arguments, but criticizing automatic currying is totally valid.
> Functional programming with immutable values is a wrong pattern for programming languages. Many algorithms, almost all actually, are naturally expressed in imperative style with mutable arrays or variables.
This is a huge jump. Any imperative solution can just be expressed as a fold of some sort and many algorithms, esp. those that use stacks, are easily expressed recursively. Which one is more "natural" is 100% subjective, but I'm in the declarative is easier to reason about than imperative camp. Moreover, the idea that "unnatural" algorithm expression implies "doesn't scale" needs much more elaboration.
> What is needed is to bridge the good things from OCaml, the type system, the pattern matching with tagged types into a modern, imperative programming languages.
> Rust is a sort of answer but they got it wrong because it is too low level about managing the memory, the ownership pardon, and everything else so programmers cannot just express the algorithm or the logic they want to implement but they have to spend a lot of mental energy thinking about ownership issues and unneeded accidental complexity like lifetime annotations.
It's not "wrong" just not what you want, and honestly the ownership model isn't that bad. The overhead amortizes somewhat as you get used to it. I of course agree there is room for more languages with ML-like type systems though!