Many of the points here don't necessarily have to do with the language, well at least to me and could easily have occured in other languages such as coding style. Sure - the language uses some sensible defaults and is somewhat pragmatic when to be pure and when to not. But in the end programming can get complex. Even if the language steers you towards practices that lower complexity (a productivity win) you still need to understand what is going on and use the right tool when appropriate.
On a side note the performance thing seems to be a myth to me. There's no reason C# or F# should be faster or slower than one another with enough effort given the same underlying runtime. Many of the functional features are moving to be lower/zero cost in F# (inline lambdas, state machines, etc). They all compile down to IL in the end so as long as you can get the IL you want does it matter? Sure it may be easier to express more performant code in one or another depending on the domain. I could argue many cases where F# was easier to write performant code (numeric, generic algo's, explicit inline functions, inline vs ref, tail rec, compile time polymorphism, avoiding virtual dispatch preferring static functions, etc) and vice versa (native interop, until recently specialised async/await, etc).
> On a side note the performance thing seems to be a myth to me.
I've always thought about the performance advantages as more related to how (FP) allows for easy parallelisation as your functions are pure, no mutability, etc .
Yes F# could be faster than C# but the compiler is missing some advanced optimisations. Right now you can do those by hand but often the code will read like C# once you are done.
I wonder if a FP compiler should actuall be able to produce faster code than for imperative style: imho knowing intention and context could lead do far superior optimizations (for loop with var for summing vs. List.sum)
Yes it definitely can! The most important optimisation (imo) is to replace pure code on immutable data-structures with imperative code on mutable data-structures.
Why not just write imperative code? Because it’s really hard to reason about.
On a side note the performance thing seems to be a myth to me. There's no reason C# or F# should be faster or slower than one another with enough effort given the same underlying runtime. Many of the functional features are moving to be lower/zero cost in F# (inline lambdas, state machines, etc). They all compile down to IL in the end so as long as you can get the IL you want does it matter? Sure it may be easier to express more performant code in one or another depending on the domain. I could argue many cases where F# was easier to write performant code (numeric, generic algo's, explicit inline functions, inline vs ref, tail rec, compile time polymorphism, avoiding virtual dispatch preferring static functions, etc) and vice versa (native interop, until recently specialised async/await, etc).