Let's look at some myths around the F# language and challenge them, based on our experience as a consultancy using F# almost exclusively for several years. We've built several of our own F# projects, guided other customers in building theirs, and trained people in using F# and related technologies like the SAFE Stack.
1. F# is hard to learn
As always, how difficult it is to learn anything depends a lot on your background, so let's consider some different backgrounds.
C# users find the F# syntax very unfamiliar at first, but they are familiar with .NET and its libraries, which they will likely also use heavily in F#. If they make heavy use of object-oriented or imperative styles, they can take some time to become comfortable with functional-first, immutable programming. If they already use C# in a relatively functional style with the latest language features, they often quickly learn how to extend this style further into idiomatic F#.
JavaScript developers also face a similar syntax barrier, but they are happy passing functions as values and usually favour functions over classes which is typical in F#. They also tend to use a data-oriented style, building data objects with no functions and passing them around, also standard F# practice. They might struggle with static typing initially but usually soon find they save more time than they lose by fixing compiler errors.
My own experience is that I started my developer career by joining a C# team. I learnt C# on the job and simultaneously learnt F# in my own time. I found F# to be a lot simpler in its idiomatic usage, mainly writing functions and not classes. I found fairly soon that I could solve problems in F# with less ceremony and less code than with C#.
Generally speaking, we've found that F# is no harder to learn than your "average" non-functional language.
2. F# is only for hard problems
In the past, F# has had a reputation for being mainly used for "maths and science". We have heard people say things like "I don't need to use F# because the problems I have aren't hard enough".
F# is a general purpose programming language, suitable for many types of applications. We tend to write business web apps and similar and we still get a lot of benefit from its distinct features. Since F# has strong support for domain modelling and has good .NET and JavaScript integration, it is actually a great fit for business apps.
And besides, writing any software that meets the changing needs of the real world while keeping the codebase maintainable is actually a hard problem!
3. You need to know category theory to use F#
Pure functional languages like Haskell often make use of areas of mathematics like category theory. One example of this is the much dreaded or loved monad. The Haskell community tends to communicate using these concepts.
F# on the other hand is functional-first, not purely functional, and it has a different culture among its users. Even though category theory concepts are used to some degree to help give F# a sound and correct design, F# programmers don't need to know about them in order to write good F# or to read the vast majority of F# code. For example, Option
may be a monad but I don't need to know or care about that to use it or talk about it.
F# does have several features that go above and beyond traditional object-oriented programming, like discriminated unions and computation expressions, but they are designed to be intuitive and usable to a programmer's mind.
4. F# code must be slow if it's immutable
F# encourages you to avoid mutation and using immutable data structures. This may be faster than you think if you haven't worked in a functional language. Immutable data structures can be designed in a way that makes them quite fast for certain operations, so you can get their benefits without much cost. See our post on Immutable data structures for more details. For general business app code they are often fast enough.
However, there are always some domains where mutation is needed to get enough performance. F# also allows you to use mutation where necessary, ideally in a limited scope.
5. F# is only for the back-end
In the last few years F# has been increasingly used to create UIs. Fable allows you to compile F# to JavaScript to target web browsers. The SAFE Stack combines F# on .NET and Fable to create full stack web apps. This is becoming relatively common today and we have used it successfully in production.
Xamarin allows you to write F# code to target mobile devices. The Fabulous project provides a nice functional framework for doing this.
The widely-used Ionide VS Code extension is a good example of a large F# codebase that is compiled to JavaScript by Fable.
6. Not enough people use F#
When considering this statement, we should ask "Not enough for what?". It's true that F# is still quite niche compared to the top 10 languages, but how much popularity do you need to use it effectively in your projects?
F# is integrated with widely used ecosystems, .NET and JavaScript, with good interop and the ability to use existing libraries. In additon, there are several well maintained libraries that provide idiomatic F# for key areas: Examples include Expecto for testing, Giraffe for web servers and Elmish for UI.
On the subject of hiring, there are fewer developers with a good knowledge of F# compared to the most popular languages. However, we have found there are many good developers who would love the chance to use F# at work, with varying degrees of experience with it but a strong willingness to learn, and therefore finding good candidates hasn't necessarily been more difficult.
Popularity isn't always a good thing either. Consider the competitive advantage that you gain from using using any technology that improves your code and your software, compared to other people that aren't using it!
Summary
We've been using F# for long enough to hear these myths crop up several times, and hope this account of our experience dispels them in a balanced way.