F# is an ML without any of the things which make ML good (modularity). It's a breath of fresh air if you're on a Microsoft platform, but if you can use OCaml, it is superior.
Hey Jon, being an F# user who is not very familiar with OCAML, I'd love to know a little more about what specifically F# lacks that makes OCAML superior. I want to know what I'm missing out on.
- native compilation without requiring some installed runtime
- Polymorphic Variants (Last I read, to be used only when regular variants are not sufficient)
- Modules and Functors (there's a proof of principle for F# supporting these)
- GADTs (allow for richer more expressive types, much more flexibility than regular algebraic data types)
- camlp4
- more pervasive structural typing, higher kinded types...type system is not weighted down by a foreign runtime
Where F# is better:
- better support for not-sequential programming in all its forms: actors with lightweight threads, parallel, async, gpu (many production ready choices), reducers (and Go style channels if they accept joinads)
- Active Patterns are a dark horse
- Type Providers are curious. They seem like dumbed down metaprogramming at first but it's one of those cases where constraints benefit creativity. Although you could certainly do what they provide (and more easily at times) with metaprogramming, I've never seen metaprogramming used that way before. And especially with the proliferation of APIs, stuff like json inference makes going to a language without them like going from 3 monitors to one.
- Units of Measure
- More libraries and Better cross platform support via Xamarin and unity3d
- #light. F# syntax is a tiny bit cleaner and surprisingly close to Python at times.
Why the above do not matter: The MLs tend to be more pragmatically focused than other functional languages and espouse using as little fancy code as possible. The core of both languages are the same, so much of the time and ignoring library choices, you won't be seeing many differences between F# and OCaml. It's more like Portuguese vs Spanish than English vs German.
I'm surprised you mention camlp4 as an advantage over F#. It is being removed from the official distribution due to the problems that it causes[1], to be replaced with extension points[2].
We use camlp4 a bit at Red Lizard Software and we are eagerly looking to move to extension points as soon as they are released.
Thanks for the great comparison! Just want to note that OCaml's GADT stuff is really great, but you can even do a final encoding of GADTs if all you have is signatures and structures (as in SML). I'm not familiar enough with F# to say—is this also possible in F#?
Thanks, this was super helpful. I'll have to spend the time going through functors this weekend to try to grok them.
But also F# doesn't allow null values, it uses the Option type as well.
F# most definitely allows null values. They might not be encouraged, you can't always assign a literal null to a type, but null is very much a first class concept in F#.
You're far less likely to run into them in F# code compared to C#, though.
Jon mentioned modularity, so what I imagine he's talking about is functors. They have a scary name (and no relation to Haskell functors) so you might rather call them parametric signatures and they allow one signature to depend upon a previously defined one. Ultimately that means that you can decompose signatures into constituent, reusable parts which is nifty sounding but transformative in how you express APIs
Functors are not parameterized signatures: they do not allow a signature to depend upon another signature, but rather a structure to depend on another structure. (However, SML/NJ has an extension called `funsig` which does what you have described).
Well, they're related at that level. Many, many things are category theoretic functors, though. It's a very general idea of a structure-preserving map between structures.