← Back to context

Comment by sterlind

3 months ago

I really wanted to like F#, and I kinda do, but it has a number of quirks, compiler issues and cracks in the design that are getting worse:

First off, the compiler is single-pass. All your definitions have to be in order. This even extends to type hints - it can't use clues to the right to deduce the type of an expression on the left. This is supposedly for perf reasons, but the compiler can become extremely slow because the inference engine has to work so hard - slower than GHC for sure.

Speaking of slowness, Haskell is surprisingly fast. Idiomatic Haskell can be within 50% the perf of C, since its laziness and purity unlock powerful optimizations. F# is eager and the compiler doesn't do anything fancy. Perf often makes you reach for mutable state and imperative structure, which is disappointing.

The OOP paradigm feels bolted on. Should you use classes or modules? Pure functions or members? It depends, what mood are you in? Unfortunately only member functions support overloads, and overloads are useful for some SFINAE-type patterns with `inline` functions, so they get a bit overused.

`ref` struct support, which is vital for zero-copy and efficient immutable data, have very primitive support. even C# is ahead on this.

Very limited support for implicit conversions, no support for type classes and no function overloading leaves F# with nothing like a numeric tower you'd have in Lisp, and makes building something like Numpy clunky.

I use C# at work, and I love Haskell, so I really wanted to love F#. But it just doesn't get the love it needs from MS, and some design decisions aren't aging well - particularly as C# itself evolves in directions that are tricky for F#'s aging compiler to support.