OCaml Criticism – Is It Still Valid?

ocaml

I am a complete newbie with OCaml. I have recently stumbled into this page listing a good amount of criticism towards OCaml.

Seeing that the page it quite old (2007): which of the bullets points listed there are still true today? For instance: is it still true that it is impossible to print a generic object?

I want to make it clear that I am not looking for a discussion of the opinions expressed therein. I am asking whether the information listed, such as the fact that integers overflow without warnings, is still correct for more recent versions of OCaml

Best Answer

This article is discussed at several places:

To summarize: yes, OCaml is not a Lisp, and no, it is not perfect (what does that mean?). I don't think the points mentioned in the blog post are relevant for day-to-day O'Caml programmers.

Having studied O'Caml, I think it is an interesting language which can help you build programs you would not even dare write in, say, C/C++/Java: for example, have a look at Frama-C.

For an up-to-date description of O'Caml, I encourage you to read about its features: the language promotes strong static type checking techniques which allows implementations to focus on producing performant, yet safe, runtimes.

Important: I am no OCaml expert: if you are one of them and see I wrote something horribly wrong, please correct me. I'll edit this post accordingly.

Static type checking

  • False Sense of Security

    This is true, but obvious.

    Static typing gives you proofs you can trust about a subset of your program's properties. Unless you accept to go all formal, an average (non-toy) program will be subject to programming error bugs which can be witnessed only at runtime.

    That's when dynamic checking techniques can be applied: the OCaml compiler has flags to generate executables with debugging information, and so on... Or, it can generate code that blindly trust the programmer and erase type information as much as possible. Programmers who wants robust programs should implement dynamic checks explicitly.

    The same thing applies to e.g. Common Lisp, but reversed: dynamic types first, with optional type declarations and compiler directives second.

  • Few Basic Types

    Still applies: the core language has not changed (or not dramatically).

  • Silent Integer Overflow

    This is the norm in most languages that integer overflow are checked by hands. I don't know of any library that would type-check operations to verify whether overflow can occur.

  • Module Immutability

    1. Author mentions Functors but I fail to see how his example cannot be implemented. Reading the First Class Modules chapter of https://realworldocaml.org, it seems that modules can be used to compose and build new modules. Of course, modifying an existing module requires source code modification, but again, this is not unusual among programming languages.

    2. "Semantically, functions are compiled INLINE"

    The reddit thread above disagrees, saying that binding are resolved at link time. However, this is an implementation detail and I think that the emphasized Semantically relates to the way functions are resolved. Example:

     let f x y = x + y ;;
     let g a b = f b a ;;
     let f x y = x * y ;;
     exit (g 2 3) ;;
    

    The above program compiles, and when executed, returns 5, because g is defined with the first version of f, just as-if the calling function g inlined the call to f. This is not "bad", by the way, it is just consistent with O'Caml's name shadowing rules.

    To summarize: yes, modules are immutable. But they are also composable.

  • Polymorphism Causes Run-time Type Errors

    I can't reproduce the mentioned error. I suspect it to be a compiler error.

No Macros

Indeed, there are no macros but preprocessors (OcamlP4, OcamlP5, ...).

Minor Language Suckiness

  • Record field naming hell

    True, but you should use modules:

    1. Two fields of two records have same label in OCaml
    2. Resolving field names
  • Syntax

    Still applies (but really, this is just syntax).

  • No Polymorphism

    Still applies, but somehow there are people who prefer that instead of Lisp's numerical tower (I don't know why). I suppose it helps with type inference.

  • Inconsistent function sets

    See the OCaml Batteries Included project. In particular, BatArray, for an example of map2 for arrays.

  • No dynamic variables

    Can be implemented:

    1. http://okmij.org/ftp/ML/dynvar.txt
    2. http://okmij.org/ftp/ML/index.html#dynvar
  • Optional ~ arguments suck

    By language restriction, you can't mix optional and keywords arguments in Common Lisp. Does it mean it sucks? (off course, this can be changed with macros (see e.g. my answer)). See O'Caml's documentation for optional and named arguments in O'Caml.

  • Partial argument application inconsistency

    I don't think it this is really annoying in practice.

  • Arithmetic's readability

    It holds, but you can use R or Python for numerical problems if you prefer.

  • Silent name conflict resolution

    Still applies, but note that this is well documented.

  • No object input/output

    Still applies.

Implementation, libraries

These keep changing every day: there is no definitive answer.

Finally,

"You should try OCaml (or, better yet, Haskell) even if you think it sucks and you are not planning to use it. Without it, your Computer Science education is incomplete, just like it is incomplete without some Lisp and C (or, better yet, Assembly) exposure."

... still applies.