“F# code is full of operators, making the code unreadable.” said a C# developer to me once. And he is not the only person to dislike F# for its operators – not specific operators, but the sheer number of operators there are.
Before continuing reading, take a moment and guess the number of operators in vanilla C# and F#.
In our typical F# code, one operator is used a lot.
The omnipresent pipe operator
A lot of code in F# looks something like this:
let data = getRawData () |> filterData |> transformData
So yes, we love the |> operator so much that we even like to be geeky with things like
F# |> I love.
But besides the pipe operator, we don’t use that many operators in our typical code. Okay, we invented the
|!> operator that stands for
|> Async.map because we use this a lot, and of course, we use mathematical operators like
* and so on. And once in a while, we use
:: to pattern match on lists or to add an element to a list. Otherwise, we prefer functions.
There must be other reasons for the myth.
The pipe operator alone probably isn’t the source of the myth. So let’s take a look at possible other reasons.
There are examples using point-free programming, as explained in Point-free programming style in F# – blog. (jayway.com) If you have never seen this, it is hard to read. But it’s completely your choice whether you want to take that route or not. We don’t.
Then there are libraries using the Kleisli composition operator
>=>, like GitHub – giraffe-fsharp/Giraffe: A native functional ASP.NET Core web framework for F# developers.
Or maybe the source is the same as for the myth that F# is for math problems only. Then in math, there are many operators! Or are there really?
And what about C#?
When I talk about F#, I typically do this to C# developers. And I heard this myth from several C# devs. So, what about operators in C#, then?
I added links to the C# and F# docs on operators and symbols in the References section. Take a quick look, and you probably can agree with me that both languages know a lot of operators (and symbols) and C# leading the count.
You may object that it is more relevant how many operators are used in everyday code (distinct number of operators and total sum of operators). And I agree.
When I take a look at our F# and C# code – we have plenty of both – there are, as written before, mainly usages of
|> in our F# code. Mathematical operators are used equally in both languages. But what stands out are the nullability operators (and symbols) in C#:
?. and even some
So overall, I’d say it’s a close race between F# and C#. Both languages know a lot of operators and symbols, and in everyday code, operators are present quite a lot. As with most myths I present, familiarity is probably the source. If you are used to all the nullability operators in C#, they are not a big deal. The same holds for the most used operators in F#. But, of course, you can go overboard with operator usage. But you can do this in both F# and C#. It’s up to you to find the sweet spot between readability and conciseness.