I have long been aware of C# as a strictly-better Java (imo), but I only recently learned of F# which appears to be an OCaml running on .NET if I understand properly.
I must say, I keep seeing very cool things for F# that really interest me.
Actually, I think this may just be OCaml that interests me as I have very little experience with OCaml but I keep seeing very cool projects crop up in various dialects of it.
Can someone with more experience with OCaml chime in and offer some opinions/articles on a few things for me?
I’ve used both OCaml and F# in anger, in production, and I’m honestly mediocre at both, but I can at least partially answer your questions.
F# is an ML, but not really an OCaml variant in any meaningful sense. Yes, it’s true that early versions of F# aimed to be syntax-compatible with OCaml, but that was always a bit of a stretch. Even if you ignore the syntactical differences, F# and OCaml have meaningfully different semantics. F# has .NET-style classes, OCaml has its own object system (which AFAICT no one uses) and its own take on the whole concept with a really neat module system. F# has workflows, OCaml doesn’t have something quite equivalent. F# has units of measure, OCaml lacks an equivalent. OCaml has abstract data types, F# does not, but F# has operator overloading and reified generics, which OCaml does not. And so on. In nearly all respects, OCaml has vastly more in common with SML/NJ than it does with F#.
The runtimes are also very different. By virtue of running on the CLR, F# has real, full-blown multithreading with a rich async system. In contrast, OCaml has a stop-the-world GC that can feel quite a bit like the Python GIL in practice. On the other hand, OCaml compiles directly to native binaries and has a simple, very easy-to-understand runtime that I feel confident I could explain to you in about ten minutes, whereas .NET in most situations is still really a VM-like affair, and requires you understand a vastly more complicate runtime situation. (Yes, .NET Core changes at least the native compilation aspect, but that cuts out a lot of libraries most .NET devs want to use today.) And again, because F# runs on the CLR, you’ve got access to the .NET ecosystem, whereas OCaml is limited to a mixture of the OCaml ecosystem (which is significantly smaller), or calling out to C libraries (which has gotten very pleasant, based on my experience, but is still more overhead than just consuming C# libs from F#).
I personally found my experience with F# more pleasant than OCaml due to a mixture of superficial issues (e.g. lighter syntax, better IDE support) and what I’d call “real” issues (the multithreading support and library situation), but, again, I don’t consider myself an expert in either language based on my limited experience. And I cannot possibly compare this to Haskell or Agda. But I hope this helps answer your question at least a bit.
F# does have abstract data types, if you have a type 'a t = T of 'a and hide the constructor in the corresponding .fsi file, outside modules can’t see it.
type 'a t = T of 'a
OCaml has an incremental, not stop-the-world, GC.
Reason might be of interest to you, as well.
I’m a big fan of the ML family, though I’ll stick with Scala (which is a great option if you’re already on the JVM) until other options get HKT. My concern with F# would be whether there’s the level of library/tool ecosystem that you’d get in OCaml (or Scala). .net doesn’t have the same open source tradition or established package management infrastructure and corresponding ecosystem yet, AIUI. (There’s nuget or some such up to a point)
The only advice I’m ever able to give people asking where to start with a language is: write some code. Solve some problems.
There’s a library for Idris which tries to do some of the same ideas, but completely as a library:
I work on scale software integrated in heavy machinery for weights and sensors, and our C/C++ code desperately needs this sort of thing. This would have prevented so many bugs.