After falling in love in it, I wrote a large project in F#, but eventually had to ditch it and rewrite in C#. A simple analysis of any F#-generated IL will reveal this.
After falling in love in it, I wrote a large project in F#, but eventually had to ditch it and rewrite in C#. A simple analysis of any F#-generated IL will reveal this.
EDIT: Just saw your reply. I do agree about the IDE -- having ReSharper, OzCode, etc., on my side is a great advantage on the C# side, even though I'm an F# fan as well.
Also at this point C# is a fine FP programming language itself. (Can 8.0 finally pattern-match tuples sanely?) The only thing missing are DU/sum-types.
Besides ATS (which is not very practical), only Common Lisp seems to accommodate to that (and maybe just because Lisp is old and had to deal with performance issues for decades), but it still lacks a state of the art GC.
Especially, it's very easy to pass the wrong values to functions (functions instead of final values, etc). Debugging this is very time-consuming.
IDE-niceness is also a factor. Devs tend to disregard this, but all the intellisense, code lens, go to, find refs, etc are huge time savers. You lose many of these capabilities (or get them in a degraded manner) with F#.
Yes, I used all the plugins, etc, but what you get is simply 2nd-grade. This is in part unfixable; the language is simply not designed with such aspects in mind.
And, as said, performance played a factor as well.
Performance wise I find it depends on what your doing. I've had nicer code run faster in F# than C# with inlining and such. You can resort to mutable coding if you have to in F# as well so I don't think its truly the case. If your using immutable data structures and writing a WPF app on top without understanding them I can see why you would get the performance hit as an example.
I haven't had a problem with Intellisense, IDE niceness (e.g. Rider, VS Code), Go To Refs seem to even work in VS Code etc. All the Resharper goodies aren't there; but after awhile you find you just don't need them as much in a more leaner language.
I have the opposite anecdote. I use F# specifically for its strong type system and domain modelling capabilities.
A method signature in C# might look like
public static void HireHandyman(string handymanName, bool sweepFootpaths, bool waterGardens, bool emptyLitterBin, bool mowLawn)
I can do in F# as
HireHandyMan(handymanName:EmployeeName,sweepFootpaths:SweepFootpaths,waterGardens:WaterGardens,emptyLitterBins:EmptyBins,mowLawn:MowLawn)
Each type listed there is a thin wrapper over the bool type, but I can add additional business logic at the type definition and it is enforced throughout the codebase at compile time (for the most part). Is it a contrived example? Somewhat. Does it prevent me from putting the emptyBins argument in the waterGardens slot? Yes, at compile time.
I do concede the lack of first-class tooling (CLI is not enough, mediocre programmers like me like designers and GUIs! shakes cane) is one of the bigger costs to using F# in particular.