https://github.com/rspeele/CSharpFSharpPhrasebook
This does not sell the language -- it doesn't show off anything interesting you can do in F# that you can't in C#. There are other resources for "why F#". This is for C# developers who are convinced that they want to learn, but are annoyed by not being able to quickly look up how to do the things that they're familiar with from C#.
http://www.fsharpworkshop.com/ http://products.tamizhvendan.in/fsharp-applied/
Once you are proficient, you will write
- less code for similar functionality
- have lot less dependency cycles
- using Option types over null helps in the long run
- improvement in productivity
The only problem is that you have attain a level of proficiency and flip the "train" of thought from OOP to Functional, and that can take some good time.
cons: performance (doesn't have to be bad but if you do things idiomatically will tend to be) tooling and other externalities (better that most niche languages but not as good as c#)
1. Immutable values by default avoids whole categories of problems. Just for one example, you can't have a data race between two threads if all the public values accessible from each thread are guaranteed immutable.
2. F# forces all cases to be handled. You've doubtless run into C# code that has a switch statement that doesn't have cases for all possible inputs, and no default case. F# doesn't have a direct equivalent of "switch" at all, but it does enforce completeness in the equivalents it does have. For example, it's illegal in F# to say something like "if foo > 1 then ... elif foo < 1 ..." since that leaves the 0 case unhandled. This is not just about better compiler warnings: it's required by the very fact that "if/else" is an expression, not a statement, so all branches must produce a value for all inputs.
3. F# has units of measure data types. Ever had an application bug because you've incorrectly passed a bare "int" value holding milliseconds to a function expecting seconds? I have. F# lets you define your units as part of the data type, so that it's a compiler error to pass milliseconds to a function expecting seconds.
I could go on, but as you can see, there really are substantial differences in practice between F# and C# code.