Skip to content

Instantly share code, notes, and snippets.

@mrange
Last active May 7, 2021 13:51
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrange/45cee653ccba0de56a45ad886b589814 to your computer and use it in GitHub Desktop.
Save mrange/45cee653ccba0de56a45ad886b589814 to your computer and use it in GitHub Desktop.
Why F#?

Why F#?

I got inspired to answer the questions posed to F# experts on "Why F#?". I have no claims to be an F# expert but I thought the questions were interesting.

How and when did you get started programming in F#?

I believe I started to look at F# around 2008. I am a language-curious person and was at the time working as a .NET developer so I naturally was excited when discovering F#.

How long did it take before you could code real world apps as much or more productively as in C#?

As I knew a bit of Standard ML learning Functional/F# was almost instantaneous. However, it took some months for me learning OO/F# to the level I knew OO/C#. I find OO/F# is mostly useful when writing programs that interop with the rest of the .NET ecosystem and as I never have held an F# job I felt no initial need to do OO/F#.

What advantages does F# have over C# and VB.NET?

In the beginning I my answer was "not that many". Now I believe F# is "obviously" the best .NET language. My list of advantages is quite long so I will just list some:

  1. Functions are as composable as values - The "dream" when writing software is to be able to compose simple functions into more complex ones. In OO languages it's easy to compose values but more difficult to compose functions. In functional languages we compose simple functions into complex functions as easy as we are composing values. We are therefore closer to the "dream".
  2. Algebraic Data types - A fancy word for something that is easy to understand and work with. Yet ADT:s are immensely useful and changes how one think about types.
  3. The unit type - C# and .NET inherits the concept of void from C. For anyone that done generic programming void is a very clunky type (Category Theory explains why). Consider Task<void>, it won't work. In F# we do Task<unit> which means there's no need for Task.
  4. Tail-call elimination - It took my a long-time to realize but tail-recursion is superior to for/while loops. However, we can't rely on the JIT:er to unroll it for us (mono doesn't support it AFAIK). If properly written F# will detect a tail-recursive function and unroll it into an efficient IL loop.
  5. No statements - For me a major disappointment with Swift (the Apple programming language) was that it supports statements. Statements don't compose, statements are "bad" and I see no need for statements. In F# the for-loop is an expression that returns unit.
  6. Computation Expressions - In my opinion the most powerful language construct in .NET. Enables you to implement your own async/await without needing to modify the compiler.

Are there any business problems that you prefer to solve, or partly solve, using a language other than F#, or do you use F# for everything?

As F# runs on top of .NET which like JVM uses JIT:ing and GC it's unsuited for embedded real-time software (which is what I do these days). I have to make do with functional C++14.

What advantages does F# have over pure functional programming languages such as Haskell or Elm?

I think purity does come at a price of disallowing optimizations that rely on destructive mutability. Immutability is a good default but real-world concerns over performance shouldn't be ignored neither.

That said I do believe F# would benefit of an pragmatic extension that allows the type-system to detect purity/impurity.

One downside is the pool of developers with experience in F# is smaller than for more mainstream languages. Please describe any experiences you have had in recruiting for F# developers?

I never have had an F# job or worked in an organization that used F# so I don't have any experience with this.

If you were recruiting for an F# developer position but no experienced F# developers were available, would you be more inclined to hire someone with a C# background, or a developer with experience in a pure functional language?

In general, I think the recruiting process focuses too much on languages and tools. I think domain knowledge and a good mind is more important than what tools a person happened to use up to that point.

That said I think a C# developer that uses LINQ and higher-orders functions daily will feel right at home with F#.

Which new feature would you most like to see in a future version of F#?

It's a hard balancing act to add new language features. One risk increasing complexity or diluting the core values. F# is already a rich language which is both good and bad (lot of things to learn). However, I think it's important that F# doesn't stop evolving. F# is great but not perfect.

As a C++14 developer one thing I miss in F# is FP-at-no-cost. Consider this:

let s = range (0, 100) |> filter (fun v -> v % 2 = 2) |> sum

Depending on the implemention F# will create function objects that fulfill some properties and the values will be pulled through the pipe using virtual calls.

The same code in C++14 would be collapsed by the compiler into a simple loop. There will be no trace in the assembly code of the function objects as the compiler deemed that they had no visible side-effects. This means in C++14 we could write functional programs that incurs no increased runtime costs over imperative programs. FP-at-no-cost.

There are libraries in F# that tries to do this but I think the best solution would be if the F# compiler would support FP-at-no-cost. It will not be easy though.

By the way, Java/C#/VB is in no way better than the F# compiler in this regard. If anything the F# compiler is slightly more advanced as it support tail-call elimination and inline.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment