OCaml is a highly underappreciated language. The biggest problem is the haphazard syntax, but if you can get over that, it's really a joy to use for application programming. You get the strongly-typed, type-inferred, functional aspects of Haskell, but without the drawbacks of laziness (for example, you can safely do IO outside the IO monad, and space leaks are less common) and with a simpler type system. There are no null pointers, and coupled with exhaustiveness checks in pattern matching, you frequently find that "if it compiles, it works". The compiler is a simple non-optimizing compiler, but it's more mature than, for example, that of Go (especially in the GC), so it beats Go in performance.
Having suffered through C++ for several years, and having enjoyed writing SML/NJ, the syntax doesn't bother me at all.
My big problem with OCaml is that the ecosystem is insanely poorly documented, and, if I understand this right (I am definitely not an OCaml expert), fractured. E.g., there's a lot of buzz about Jane Street's library, but, as far as I can tell, your code uses only their library or the built-in one, but not both. There's also several different build systems (ocamlbuild and ocaml-make spring to mind), and it's not clear to me which is preferred, nor how to deal with the fact that interesting-looking libraries seem split on which to use, meaning I'm guessing I need to somehow glue the systems together. There are several libraries for unicode support, but again, I don't know which (if any) is the "normal" one, and various libraries appear to use different unicode support libs, so I have no idea whether they can safely be mixed in a single application. And then there's this whole GODI thing, which appears to be kind of like RVM or perlbrew, but kind of its own thing. And so on.
What I'd love is a well-written, super-opinionated guide that says, "Okay, use ocamlbuild for building, use Jane Street's Async lib for multitasking, use GODI to manage your system and here's how you do that, grab this Unicode library, and you'll be good to write stuff that other people can easily use and maintain."
I know, and I'm tepidly excited, but I'd had high hopes for Practical OCaml, too, and ended up being sorely disappointed. There's lots of good reasons to believe that Real World OCaml will be a totally different beast, but I'm trying to hold my enthusiasm until we get a bit closer to when it ships.
While I agree that C++ templates when used for anything but simple type generalization, are a gross, gross part of C++. I'd hardly call that core to the C++ syntax.
However, I'd also argue that using templates to that extent is misuse. Eventually, it becomes a better idea to simplify your approach, or invest in a decent macro preprocessor.
I for instance feel that many of the template heavy boost libraries, while powerful, only decrease maintainability of a system in the long-run.
While I agree that C++ templates when used for anything but simple type generalization, are a gross, gross part of C++. I'd hardly call that core to the C++ syntax.
You're welcome to feel that way, but template abuse is simply a given with 99% of the C++ that crosses my screen these days. It's pervasive in Boost, it's pervasive in the STL (especially in C++11), it's pervasive in libraries like ATL and WTL. You can write C++ that avoids these parts of the language, but you are in the distinct minority in doing so. I think my complaint about C++ syntax is fair.
I'd hardly call the STL, ATL, or WTL particularly heinous abuses of the template system.. And the syntax, is in general, pretty reasonable... Boost on the other hand...
In fact I think this is the only software that I know is written in a functional language that I use on a regular basis. I've always figured that said very good things about OCaml. (Not that I've ever gotten around to learning OCaml, mind you.)
But, most FP languages have only recently started gaining real traction outside academia. There are some great tools written in e.g. Haskell: pandoc (a document converter), Hakyll (a static site generator), Darcs (version management), xmonad (an X11 window manager), git-annex, and multiple web frameworks (Yesod, Snap, Happstack).
In recent years, some important foundational libraries have been developed (bytestring, text, vector, repa, conduit/enumerator, etc.). I can imagine that it's pretty much the same in OCaml and F#.
Well the revised syntax (http://caml.inria.fr/pub/docs/manual-camlp4/manual007.html) is completely implemented as a camlp4 (p5?) extension, so if you have enough patience you can write another extension to replace the syntax with whatever you want, I suppose.
1. Global interpreter-lock, and the effect that has on the ability to write multi-threaded programs.
2. False negative proof, the same issue Haskell has. The fact that it's "had its chance" to catch on and hasn't done so marks it as a failure (or "not production ready") in the eyes of people who make decisions.
Scala has better odds than Ocaml and Haskell for this reason alone.
3. The perception that there's a lack of libraries relative to, say, the JVM. I say "perception" because Ocaml has bindings to leverage the C libraries. However, it doesn't have the Java libraries, and those are proving to be an important asset even in un-Javay languages like Clojure.
On Scala, since I'm resigned to the fact that it is more likely to win (and find I like the language a lot) the unresolved question in my mind is: is Scala an acceptable ML? I like Scala a lot and I'm leaning toward "Yes", but I haven't worked with Scala on something big enough to have a fully formed opinion there.
4. (Small one.) The name. I would like it just as much if it were called FishGuts, but names matter in adoption. I think Ocaml's a fine name, but I'm weird.
I do not think Scala is an ML. The use of the word acceptable and indeed restricting it to an ML derivative loses the point of what Scala is supposed to be. Scala is supposed to be something different: a successful melding of OOP and functional. And it is the best at that I have seen. It succeeds on this better than the next biggest contender: F#, which is the most acceptable ML, IMO. F# is more typically functional, using the usual Hindley Milner Inference and sharing a core with OCaml but with significant whitespace. So it can be very succinct. Typically functional idioms like algebraic data types, Piping, point free, currying and combinators is more natural to F# than Scala's more OOP way. I prefer F# to Scala but that is merely a subjective preference.
There are a number of things that Scala does naturally that are cumbersome in other languages because of how it manages to meld a powerful combination of orthogonal features. To use Scala as just another functional language is to miss its power. Those who criticize OOP have not used a language that does it right. Abstractly, in a simplified categoric setting, we can consider OOP (objects as coalgebras) and FP (algebraic data types) as duals of each other. A proper unification of the concepts gives something more powerful than either. I think Scala comes the closest. Sure you can be 100% functional in it, or replicate Java but to call it one or the other is to make the same mistake as to say that light is both a wave and a particle and think you understand what that means.
I thought it might be until I tried OCaml, and the difference between type inference that only works on locals and pervasive inference is huge. Also the fact that JVM interop makes it hard to avoid null pointers is a big strike against it.
Still, I agree that the odds are in its favour vs OCaml for things that don't need to be close to the metal.
The global interpreter lock is a large one IMO. One of the huge advantages of type safety is that you can use types to help enforce thread safety rules, but if the interpreter itself can't handle it, that's a huge problem!