The Case for F Sharp
All developers seem to be saying the same thing: these days there is just so many new things to learn that it’s difficult to keep up.
For .NET developers, just keeping up with the framework changes can be challenging. It doesn’t seem long ago at all when ASP.NET MVC 5 and Web API 2 were the hot new things. Now some people are already starting to describe them as legacy!
For example, .NET Core is hugely different to what we had before. Technology that involved a good investment to learn not long ago has been either substantially changed or replaced with the recommendation of doing it yourself using JavaScript, an ecosystem which has created 17 new must-have frameworks in the time you’ve just spent reading this paragraph. Depending on who you ask, as many as two of the new three tools that have only just replaced ASP.NET bundling are already dead.
Keeping up with it all can sometimes feel like a lot of effort to go nowhere.
So why learn a new language when an older one already does the job? Do the benefits of learning it outweigh the effort involved? Isn’t it better to focus on writing good code in the language we already know and on just getting things done? Or could it actually be a time-saver over the long run? And could it make us better programmers regardless of which language we end up choosing to use?
When looking at investing in new technology, finding the right perspective can be the hardest thing
In the land of .NET, perhaps the biggest innovation in recent years has been the evolution of the F# programming language. It is a beautiful language, and whether or not you like alliteration, you’ll find it concise, convenient, correct, concurrent and complete!
And contrary to common belief, it is not a new and immature technology, but one that has been continually evolving for over a decade now.
But should you learn it, or adopt it into your organization?
In order to shed light on all of this, it is my great pleasure to introduce some very special guests:
Mark Seemann
Mark Seemann is a Danish programmer based in Copenhagen, Denmark.
He is the author of Dependency Injection in .NET, has created 8 courses with Pluralsight, and is active on GitHub and Stack Overflow.
He has contributed to renowned automated testing tools including AutoFixture, FsCheck and xUnit.net.
Kit Eason
Kit is a software developer and educator with 30 years of experience in industries from automotive engineering through university supercomputing to energy trading. He currently works as a senior developer at Adbrain.
He is a Pluralsight author with courses including F# Jumpstart and F# Functional Data Structures.
Kit is a regular speaker at SkillsMatter in London, and various conferences and meetups. He has also appeared on the .NET Rocks! podcast.
Dave Fancher
Dave is the founder of Achiiv Solutions, LLC in Indiana, a three-time Microsoft MVP, the author of The Book of F# from No Starch Press, Pluralsight author, and .NET Instructor at Eleven Fifty Academy.
He has been building software for more than a decade with an emphasis on Microsoft technologies.
Dave is active within the software development community and has spoken at numerous events throughout the United States.
Alena Hall
Alena has programmed in .NET since early childhood, became a Microsoft Certified Professional at the age of 16, and now works as Chief Solutions Architect.
She leads multiple Software Engineering teams across various stacks including Java, Scala, C#, F#, Python and R. She architects distributed cloud programming, real-time system modeling, higher load and performance, big data analysis, data science, functional programming, and machine learning.
Alena is on the board of trustees at the F# Software Foundation, speaks at conferences and hopes to bring the results of the her research into F#.
She aspires to make F# an even more powerful and mighty language.
Scott Wlaschin
Scott has over 20 years’ experience in software development, design and architecture, covering all aspects of business software. Starting off with C and Pascal, he later became active in the Los Angeles Smalltalk community.
A few years later he switched to using Python and .NET, and then started exploring the concepts of functional programming, leading to F#.
He is the creator of fsharpforfunandprofit.com, and has done many F# presentations at conferences and user-groups around the world.
Mike Hadlow
Mike has over 18 years experience delivering mission critical enterprise software projects, including flight status systems, CRM,
e-commerce, and a pathology lab management system.
He is the author of EasyNetQ, the primary .NET API for the RabbitMQ messaging solution, and founder of Brighton ALT.NET
He has given a number of talks at SkillsMatter and appeared on .NET Rocks
Ashic Mahtab
Ashic is a Microsoft MVP since 2009 with six awards.
As a big data engineer at Elsevier, he works with Spark, Amazon Web Services, Hadoop, EMR, Scala and other technology to build solutions ranging from implementing recommendation engines to exposing APIs in the cloud.
As director of Heartysoft Solutions Limited he has worked with clients around the world on more than 70 projects.
The Questions
I asked each developer eight questions:
- How and when did you get started programming in F#??
- How long did it take before you could code real world apps as much or more productively as in C#?
- What advantages does F# have over C# and VB.NET?
- 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?
- What advantages does F# have over pure functional programming languages such as Haskell or Elm?
- 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?
- 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?
- Which new feature would you most like to see in a future version of F#?
How and when did you get started programming in F#?
Mark: I originally started in 2010, I think it was, because I was doing the technical review for Tomas Petricek’s book Real World Functional Programming. At that time, I regularly reviewed books for Manning, and this one was suggested to me by the editor. Before that, I’d heard little about F#, but I was curious, because I didn’t understand what this functional programming was.
I loved the book, because it teaches F# and functional programming by comparing various concepts and language constructs with corresponding C# code. I felt a deep connection with this style of thinking. At the time, I was becoming comfortable with LINQ in C#, but this book explained how most of LINQ was well-known functional patterns. It put into words why I was changing my C# writing style. It resonated with me on a deep level.
Kit: Funny story. A few years ago I was working at a large financial services company and I happened to overhear someone mention F#. I suggested to my manager that we look at this new language and he said:
“Don’t bother, F# is just FORTRAN for .NET”.
And I thought — that can’t be true, can it? So I looked into it further and the rest is history. Perhaps the guy was a genius of reverse psychology!
Dave: I started working with F# in late 2012 after first learning LINQ then hearing Richard Minerich and Phillip Trelford talk about it on Hanselminutes. How they described the language really resonated with me. Once I started more formally learning the theories and patterns behind functional programming there was no turning back.
Alena: I discovered F# 5 years ago, around the same time I discovered Scala and functional programming in general.
I found out that there is a functional language based on CLR that I can use to build .NET systems and apps. The first inspiration to try it out was originating from my conversation with programming Community friends, we were talking about various software engineering paradigms: discussing OOP, functional programming, the mind shift and all those things.
I am that kind of person that loves mind shifts and brain explosions, so I immediately started looking for the information about functional programming paradigm, purely functional algorithms and data structures, practical application of it and interoperability with existing infrastructure, runtimes and frameworks.
F# caught my attention as a great language to use if I want to write both functional and OOP code on CLR.
Scott: When I was younger, I used to love learning new programming languages — the more unusual, the better!
I learned Forth, Icon, Smalltalk, Prolog, Modula-2 and -3, etc., and in the process discovered that there were many radically different ways to think about programming. Whole new universes opened up in front of me!
And then I got sucked into mainstream development and left all that behind.
In 2011, I had been using C# for almost 10 years and was getting bored and restless. I’d heard of functional programming but I’d never actually gone to the trouble of exploring it.
I looked around for a language to learn, and realized that I had F# right in front of me, already installed on my computer as part of Visual Studio. So it was an easy decision to start there. I remember watching Luca Bolognese’s Introduction to F# and being blown away by the simplicity and power.
Mike: Looking back in my blog archives I can see that the first mention of F# is a post from December 2006, where I wrote a little F# Conways-game-of-life implementation. So it looks like I’ve been following the progress of F# for about ten years now. I can’t remember how first heard of it, but it made quite a splash in .NET community when it was first announced. For many of us it was the first time we had even heard of functional programming.
Ashic: I started around 2012, when F# 3.0 was about to come out. I was introduced to formal functional programming, and the joy of Haskell, as part of a Functional Programming course at Oxford University.
I’d had brief glances at F# 2.0 before, but doing the Haskell course made me quite keen on functional programming. Back then, I was working almost exclusively on .NET, and F# was the only realistic choice to leverage most functional programming constructs.
How long did it take before you could code real world apps as much or more productively as in C#?
Mark: I had at least one false start. In 2011 and 2012, Visual Studio support for F# was horrible. I tried to write some professional code in F#, but ran into too many problems and eventually gave up. Not because of the language, but because of the poor tooling and the awkward interop with the ‘rest’ of .NET.
I went back to C#, but was forever infected. I began to write all my C# code using only immutable classes with structural equality, but after a couple of projects written in this way, I’d learned that while I found the application architecture more than satisfactory, this required too much boilerplate code.
So I decided to bite the bullet and go back to F#. In the meantime, the tooling had improved enough so that I could be productive. It took me a small project — perhaps a couple of months — to begin to feel at home with F#. Since then, I’ve written C# for money, but F# became my language of choice.
Kit: Two weeks of 1-hour sessions sitting in a coffee shop before work. Learnt from the “Expert F#” book, which I highly recommend.
When the time came to write my first real world program (to fix a large amount of corrupted XML), I was able to write the F# program in less time than its predecessor, a Delphi program, took to run.
Dave: At first I really just played around with the language but once I got serious about it, I was able to be productive with it fairly quickly, say, within a month or two.
I was (and in many ways still am) a novice with functional programming, but the syntactic niceties as well as the streamlined data types such as records and discriminated unions made it much easier to express the intent of the code.
Alena: It took some time for me to understand the theoretical part of functional programming concepts and the new philosophy, so that I can better understand F# language constructs and syntax to apply it in the way language is designed for.
From my personal experience, being a passionate for technology fast-learner and autodidact, it took me a few months to a half a year to be able to feel that my code is written well. Of course, after that period I’ve been discovering tons of new aspects and small nuances of F# and functional programming on the real world problems.
The biggest struggle for me was to force myself to not try to write F# code the way I usually code in C# or Java. To paraphrase, it’s necessary to properly digest the functional programming paradigm in your head and then all the pieces will match by themselves.
There is a stereotype that functional programming is hard to grasp, maybe because of lots of math in theoretical papers, words like functors, monads, zygohistomorphic prepromorphisms and other scary terms.
In reality it is not so hard, but it’s easy to get lost in theory and my advice is to focus on the fundamental concepts, but always combine it with practice and move forward with the real-world tasks. Another important thing that helped me to get started so quick and smooth is the F# Community that is exceptionally friendly, useful and responsive.
Scott: At first, like many people, I found F# code strange and obscure. However there were a few things that made it easier for me, I think.
First, I had been using Python for many years, so I was not at all worried by the lack of curly braces.
Second, I was already familiar with using lambdas and standalone functions, partly from Python, but also (perhaps surprisingly) from Smalltalk, which uses them extensively for control flow. There is no loop syntax in Smalltalk, for example, and methods like “select” and “collect” are used instead.
So after a while, it did get easier. Since I was self-taught, and was doing it only intermittently in my spare time, it took me a year or so to feel truly comfortable. I think if I had done F# full time, with support, this stage would have gone much faster
One thing I started to do (and I recommend this to anybody learning anything new) was to try and explain F# to other people. Trying to explain it will force you to understand it more deeply. There is nothing like it for accelerating your learning!
This eventually led to me starting my blog. I would not be comfortable posting about something that I didn’t know about properly, so I every time I want to learn something new, I force myself to write a blog post about it!
Mike: I’m not sure that’s the case even now. My periods of doing of full-time F# development have been brief with long gaps in between.
Compare that to 15+ years of full-time C#, and even with F#’s many benefits, I still spend too much time reading docs and Stack Overflow to make it more productive than C#.
Ashic: I got quite efficient within one or two weeks. The main struggles were around dealing with C# interoperability. Unlike JVM projects where Java and Scala code can coexist in a single package, C# and F# can’t coexist in a single assembly.
Doing pure F# work was easy, but dealing with missed projects proved challenging. Also, many first and third party components were built with C# in mind. So, using them from F# was a bit cumbersome. Overcoming these challenges… well… even now, some of these issues do pop up from time to time.
In terms of pure F# projects, I felt comfortable within a couple of weeks, and started preferring it to C# soon after.
What advantages does F# have over C# and VB.NET?
Mark: In general, it has better defaults: types are immutable be default, they have structural equality, and nulls aren’t valid values.
More profoundly, though, it has algebraic data types. This means that data types fall into one of two groups: product types and sum types.
C# and VB.NET also have product types. We call them this because the number of possible combinations of a complex type is the product of all the possible values for each consistent type. Imagine that you have a class with a byte and a bool property. A byte can be one of 256 different values, and a boolean can be one of two values, so the number of possible combinations is the product of these two numbers: 512.
A sum type, on the other hand, is a type that can be only one of several mutually exclusive cases. A sum type consisting of either a byte or a bool has a total of 256 + 2 = 258 possible values.
Sum types enable to you to declaratively model finite, mutually exclusive cases. You can, for example, model a type that either contains, or doesn’t contain, a value. This is called an option type in F#, but is also widely known as a maybe. You can also model a type that is either a success or a failure. This is often known as an either.
Such sum types gives you an axis of domain modelling not available in C# or VB.NET. Once you’ve learned to model domains with a combination of product and sum types, you feel like you’re missing your right arm when you have to go back to C#.
There are many other advantages to F#, but I’d like to point out one other advantage that I find crucial. In F#, you can’t call a function, or use a type, before you’ve defined it. If you come from C#, you’re likely to find this annoying, but it’s a colossal benefit, because it prevents cyclic dependencies.
You simply can’t write spaghetti code in F#; the compiler will not let you.
Kit: This came up in a Reddit thread a while ago, after someone wrote an article saying there was “no compelling technical advantage“. I looked at the F# file I randomly had open at the time I noticed the article, and this was the list of advantages which were expressed in that one randomly chosen 115-line file:
- Type providers
- Immutability by default
- Record types
- Comprehensive libraries of higher-order-functions for collections
- Forward pipe operator
- Backtick naming
- Computation expressions
- Discriminated unions
- Pattern matching
- Concise OO class syntax
- Strong typing
- Type inference
- Tuples
- Custom operators
- Powerful generics
- Strongly typed string formatting
- No ‘return’ keyword (last-expression returns)
- Functions as first class values
Stepping back from the details, the core advantage is that F# makes it easier to Make Illegal States Unrepresentable (MISU). The most important features of the language contributing to MISU are Discriminated Unions and Pattern Matching.
A key psychological point is that until you understand and accept that MISU is important, the supposed advantages of F# are going to be meaningless to you.
Some people are willing to suspend disbelief until MISU comes into focus for them; others want to see an advantage without a change of mindset. People in this second group are always going to be disappointed.
Dave: The biggest advantages that F# has over C# or VB are the enhanced type system including better type inference, more expressive types such as first-class tuples, records, and discriminated unions. Pattern matching is something I really miss when working in C# and I haven’t really found a way around that yet.
I’m not particularly familiar with VB’s syntax but I definitely find F#’s lambda syntax much cleaner than VB’s which is reminiscent of C#’s anonymous functions as well as JavaScript’s inline functions.
In regard to coding style, F# enforces things that the other languages don’t. For instance, I prefer F#’s top-down approach because it forces us to organize our code and actively prevents unintentional circular dependencies. Furthermore, the default immutability prevents unintended side-effects and actively forces us to think about the consequences of overriding the default behavior. This immutability, of course, naturally lets us write asynchronous or parallel code often without adding the complexity of synchronization mechanisms.
For me, F#’s functional-first approach more closely matches the way I think so concepts like curried functions, partial function application, function composition, and pipelining all came naturally to me and felt like a more natural way to structure computation.
Finally, I see functional programming as the natural next step for both SOLID and Clean Code. When you distill the concepts behind the principles and guidelines, you can see where things like single-responsibility, DRY, and the like ultimately converge back on the central concepts of functional programming.
Alena: In my opinion, F# is the best programming language to use for building applications on the .NET platform. It increases developer productivity, provides the advantage of the functional paradigm to enable simpler code solutions for complicated problems. It’s good for domain modeling, any computational code, exploratory programming and prototyping.
F# has a great type providers feature that helps to work with various data sources or even combine the code with other languages, for example R language, which is widely used with F# for data science, machine learning experiments and complex visualizations.
It has a great way to access standard JavaScript libraries in a type safe way, and a good example of this is the Ionide plugin for Visual Studio Code and Atom, written completely in F#.
Another advantage is the simplicity of building cross platform solutions — all you need is to have .NET, Mono, or CoreCLR, get Paket for dependencies management, clone ProjectScaffold repo, build it and you’re all set for plotting your project.
The language and the majority of frameworks are completely Open Source, which gives us lots of advantages, transparency and opportunity to contribute and find collaborators for F# projects.
My favorite part of F# ecosystem is presence of cutting edge frameworks such as MBrace. It is a distributed cloud based system for intense big-data intensive computations and data storage, created in F# from scratch. MBrace is based on the computation expressions feature of F# that allows a developer to write cloud based code as easily as on local machine environment. It works perfectly on Azure and has current work in progress on an Amazon Web Services provider.
If you are into distributed systems and big data computational stuff, have a look at MBrace and other drivers for frameworks like Storm for F#, Spark CLR, Zookeeper, Cassandra and other projects.
Another benefit of programming in F# is more opportunities for interesting challenging jobs, and looking into statistics — average salaries for F# Software Engineers are generally higher than C# ones.
Lots of startups and pretty big companies like Jet are using F# to build their products. Looking through the language interoperability — we can easily use C# libraries and frameworks from F#.
Scott: I’m a high-level guy, and so I tend to think of programs in terms of domain models rather than hardware. The algebraic type system in F# is fantastic for domain modeling, and one thing I miss in C#.
Also, the defaults in F# are different from C# — immutability by default, structural equality by default, no nulls, and so on. This means that if you are lazy, like me, you will tend to write better code without even trying!
Finally, I love that it is a very concise, low ceremony language compared to C#. Unlike some hardcore functional programmers, I have always enjoyed using dynamic languages like Python. A lot of that pleasure is due to how lightweight they feel compared to mainstream statically typed languages like C# and Java, and how easy it is to get immediate feedback rather than waiting for a compile to complete.
But thanks to the lightweight syntax and type inference and the REPL, I can use F# in the same way that I use Python, with the added benefit of type safety, which in turn means I don’t need to write so many unit tests.
Mike: I really like Mark’s characterisation of F# as C# with all the bad bits taken out. Not having nullable, mutable types by default is a simple change, but makes a huge difference to software reliability.
The excellent ‘chainability’ of functions and syntax such as match statements are things you really miss when you go back to C#. I probably overuse Computation Expressions too
Ashic: Most functional languages follow similar patterns for many things, and these tend to be quite specific. Having roots in lambda calculus, it is quite mathematical in nature — in a good way.
Functional code tends to be easier to compose, test, and reason about. It makes creating abstractions straight forward, and without doing it via indirection hierarchies hooked together by some reflection magic via some container.
Preferring immutability, and using proper structures (e.g. as opposed to nulls) can simplify things, and mitigate a lot of potential bugs. Separating definitions from executions — as is common in functional languages — prevents subtle issues from arising, and greatly increases testability.
Then there’s the nicer, terse syntax.
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?
Mark: F# is my first choice for .NET development. I will not choose C# or VB.NET unless circumstances force me to. This can happen if I’m collaborating with a team that doesn’t want to work with F#.
There are a few niche scenarios where F# is a poor fit. One example is with the Razor view engine, which relies on C#. If you want to use Razor, you can’t (to my knowledge) use F#, but then again, I haven’t used Razor for years.
So I will, for all intents and purposes, use F# for all .NET development.
Kit: I use C# where the existing tooling and patterns make it the easier path — for instance if there is a better template for something like MVC or WPF.
Dave: I definitely prefer to write most of the back-end logic with F#. Given that we can consume our .NET libraries of choice from within our F# code.
That said, if I were starting a new application today and had full control over the language selection, I’d probably at least try building at least part of the front-end components with F# as well.
Much of the reason I’d likely stick with C# for front-end components is that out-of-the-box, C#’s tooling support is much stronger than F#’s although there are now a number of extensions to address at least some of this concern.
Alena: Being a multi-platform and multi-stack architect I am not tied to any particular runtime and I’m used to work with many languages and technologies. When I work with .NET I use both C# and F#.
It’s convenient to do data modeling in F#, literally making the architecture carcass in F# just as a sketch and deciding which parts are better for which language.
In the most cases projects are already written in C# but I can use F# for new parts that are really good ground for F# usage.
Scott: I personally tend to use F# for everything now. There are some areas where the C# support is much better (e.g. WPF), and if I were working in those areas, I might use C#.
The libraries and frameworks for F# are improving all the time, though. For example, I can do all my database access using SQL type providers, and implement my web services using Suave or WebAPI, so I haven’t felt the need to use C# for some time now.
Mike: Given the freedom to choose frameworks and libraries, F# is a general purpose programming language and can be used to solve any problem. The biggest headaches arise when a useful library or framework doesn’t have a suitable alternative in F#, or doesn’t have F# wrappers.
The fad for ‘fluent interfaces’ in C# libraries causes all sorts of problems for the F# developer. To be honest though, I still do 90% of my work in C#, but that’s mainly because of client requirements.
Ashic: I’d prefer to use F# for almost all projects on .NET. Often though, when working on a less important project that needs a web front end, and there’s a team in place who have no functional background, I find myself using C# and MVC; it’s commonly known, and can do the job.
Last time I tried, WPF with F# wasn’t exactly plain sailing.
What advantages does F# have over pure functional programming languages such as Haskell and Elm?
Mark: The main advantage of F# being non-strict is that it makes it easier to interoperate with the existing .NET stack.
If you’re already a .NET developer, it’s not that hard to make the transition to F#, because you can concentrate on learning a new language, and a new paradigm, while you can still use your existing knowledge of the .NET framework.
When I started writing F# code, I wrote object-oriented F#, and gradually learned how to solve problems in a functional way, instead of an object-oriented way. F# allows you to do that, and I think it’s a great benefit while you learn the language and the paradigm.
Once you become comfortable with both the syntax and the functional paradigm, this is less of an advantage.
There’s another advantage of non-strictness, though, and that is that you can sometimes get better performance out of mutating, imperative code.
If you have performance-critical code, you can rewrite small parts of it in an impure imperative style, and squeeze better performance out of it.
Kit: I haven’t tried the others: F# is my first functional-first language (unless you count SQL and Excel!). My guess — and it is a guess — is that sometimes the human mind requires sort of breathing space, which is embodied by the ability to create and mutate state. Maybe pure functional languages require a level of holistic perfection that isn’t compatible with the way many people think.
In simpler terms, I really like F#’s mixed-paradigm approach.
Alena: The language is flexible in not locking you in just functional programming approach, you can still write object-oriented code if you desire. Haskell is a great and powerful language, but doesn’t have enough level of compatibility with other major programming languages and platforms to be used in the industry much more widely.
However, languages like Haskell and Idris are used by some companies for various use cases, from concurrent systems to safety validation software. Clojure on the other hand has easy access to Java frameworks that indicates the level of interoperability. The language originates from the LISP family and has the corresponding syntax.
I haven’t used Clojure or Haskell for any systems I’ve built, but know a lot of successful applications of those languages, they are pretty popular in functional programming circles.
F#’s biggest advantages over them are compatibility with existing .NET ecosystem, languages and frameworks, not being locked into just functional way of doing things, and the simplicity of getting started and getting to know the language, which is a super important factor.
Scott: I like F# because it is pragmatic, and the community is focused on solving real programs. Haskell has a research background, and many valuable things have come from that, but it was never designed to be a popular mainstream language.
I think that F# does have a chance to be a mainstream language, because it has Microsoft and Xamarin supporting it, and it can piggyback on all the work that is put into the .NET platform, such as CoreCLR and .NET native.
Mike: F# lives in a well established ‘enterprise’ eco-system. It’s very easy to move to F# development if you’re already working in a .NET environment.
Although having said that, the ugliest bits of F# are the parts that are designed to do interoperability with C#.
Ashic: It runs on .NET, and it has Type providers.
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.
Kit: Where I work in London, hiring good people with modern skills is always a problem. The F# element of the requirement is actually a great differentiator that an employer can use in attracting the best.
The concrete evidence for this is that recruiters are starting to mention F# when promoting jobs which actually have no F# content. This is incredibly annoying: but it also tells you that an F# element to a role increases your pool of quality candidates.
Dave: This is the constant struggle with F# and is one I’ve grown weary of and I don’t know how to solve. F# truly is an amazing language but in my opinion, too many “traditional” .NET developers seem to take one of three views:
The first view is that C# (or object-orientation) is good enough so why use anything else?
This is a valid question because C# and VB are a very capable languages and object-oriented is an established paradigm. But these aren’t perfect languages (not to imply that F# is) and using them simply because they’re good enough indicates a willful ignorance toward how things could be different.
By that I don’t necessarily mean “better” but by proactively avoiding the approach that F# offers these developers are hiding from the fact that there are alternatives that may or may not lead to better solutions; by taking this approach they’re not offering their customers the best solution but simply the comfortable one.
The second group seems to view adopting F# as an either/or proposition in that they think that using F# would somehow prevent them from using C#.
In reality, F# represents the greatest opportunity yet to realizing the CLR’s original promise of letting us write code in the language best suited for the problem. C# and VB are such similar languages that it often doesn’t make sense to combine them within a project but F#’s functional-first approach is a radical departure from object-orientation and is indeed sometimes more suitable for a given programming problem.
The third group seems genuinely interested in the language but hesitates about adopting it because “no one else knows it” or “but my team would never go for that.”
To me, these are horrible reasons to not at least learn the language. First, even if one doesn’t use the language from day-to-day, it will most definitely change one’s thinking. I think this is especially useful for traditional .NET developers because F# interacts differently with the CLR than C# and VB and therefore it can change how we approach coding in those other languages. The other reason these excuses are horrible is that they assume things about other people that may or may not be true.
Anecdotally, I see more and more developers at least showing interest in F# so to assume that no one else knows it or would learn it is misguided at best. Finally, if this mindset was the norm, we’d all still be writing software with COBOL (or worse).
Each of these groups may have distinct public reasons for not wanting to adopt F# but I think there’s a common underlying reason: fear of the unknown.
F# is a very different language than C# and VB and it looks very foreign to someone with an object-oriented background because it is. Looking at the functional language and concepts for the first time can be intimidating because it evokes feelings of starting over and helplessness.
But getting over that hurdle can be liberating because it opens up an entirely new world with its own ways of thinking that can complement that which we already have and ultimately make us better problem solvers and therefore better developers.
Outside of people’s reasoning for not adopting F# the bigger problem I see is that C# is gradually becoming more functional.
With generic delegates and lambda expressions already in the language, expression-bodied members added in C# 6.0, and more things such as first-class tuples and pattern matching likely on the way in C# 7, the divide between the languages is diminished.
I still think that things in F# like curried functions, units of measure, and type providers are great selling points but I do see increasing overlap between the languages and pragmatically speaking, that makes it more difficult to justify introducing F# to an environment.
Alena: The pool of software engineers with F# experience is smaller, which is understandable, because the language is younger than C# and used less than C# that leads to the conclusion that F# developers are rarer and generally have experience of F# after languages like C# or Java.
Speaking about finding F# developers for some project, it is important to look not at how perfectly a person knows F#, but at how well and fast that person can learn and solve programming problems.
Living in the new era of technology we already know that programming approaches, frameworks and libraries constantly change and evolve. It all depends on the company and requirements for the project, urge and other factors.
It is always good to find the ideal software engineer with the skillset that fits 100%, but we’re not always so lucky. In general, potential candidate should have good problem solving skills, be a fast and high quality self-learner to keep up with modern tech flow, of course, experience in any other object-oriented or functional languages, and other details related to project necessary.
Another solution is to start applying F# inside the company with the help of existing C# developers, because they are perfect candidates for exploring the new language and already have knowledge of the project and company.
Scott: I have not had any trouble finding F# developers. The pool of developers may be smaller, but using a non-mainstream language means that you automatically have a useful filter on applicants. Only enthusiastic people who like to learn new things will apply!
Paul Graham wrote about this many years ago, and called it the Python Paradox. Now Python is mainstream but the underlying principle still applies.
Mike: I don’t have any experience recruiting for F# developers. In both cases where I’ve used F# in a commercial environment it was because a majority of the team (of existing C# developers) wanted to use F#.
Ashic: In almost all cases, I’ve helped colleagues pick up F#. I’ve never been part of a team that hired specifically F# developers. Quite often, they recruit for .NET, or even C# developers, and tell them to learn F# if needed.
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?
Mark: I think it also depends on what that developer is being hired to do.
If the task is to build a forms-over-data enterprise application, I might favour a C# developer, because such a position requires knowledge of the .NET stack: how IIS works, how you communicate with SQL Server, how .NET works in general, and so on.
On the other hand, if the task is mostly to design a reusable API, or implement a complex algorithm, I’d most likely favour a programmer with functional programming experience. It still depends, though.
I think an OCaml programmer would be a better fit than a Haskell programmer, who again would be a better fit than a Clojure programmer, or an Erlang programmer. I have nothing against Clojure or Erlang programmers, but those languages are fundamentally different from F#.
Kit: I would happily look at both subsets and make a decision on other criteria.
Dave: As with anything, there are tradeoffs and while a functional background would be helpful I’d likely lean toward someone with a .NET background because, like C# and VB, much of F#’s power is derived from the .NET ecosystem rather than the language itself.
It’s true that F# is in many ways naturally more powerful than C# or VB in terms of its expressiveness but what are any of those languages without the support of the libraries that we all include in our projects?
Alena: It absolutely depends on the project, company and budgets.
C# background developers are more common on the market, purely functional developers are rarer, but might have better feel of functional paradigm, data structures and algorithms, which extends their ability to solve functional and algorithmic problems big time. C# developers might have better knowledge of .NET ecosystem and infrastructure, which might be more important in some situations.
Scott: I would not hire based on their current language skills, but on how well they can learn the domain, how well they communicate, how conscientious they are, etc.
I would expect that a curious C# programmer could learn F# in a month or two, given proper support and training.
On the other hand, I would not want to hire someone who did not care about understanding customer problems or the user experience, even if they were a world expert in Haskell.
Mike: If I was going to hire a C# developer into an F# role, I would at least expect them to show an interest in F# and to have done some hobby/side project in it. Experience shows that motivated C# developers can get up to speed with F# fairly quickly. If I could find a Haskell developer who was keen to get some F# experience I’m sure I would consider them for an F# role, simply for what they could teach me about functional programming.
Ashic: This is an interesting question. I think a functional mindset is quite useful, and picking up .NET nuances wouldn’t be too hard for somebody who’s got the right mindset. As such, I’d go for the latter, but would hope they’d have some experience in .NET.
Which new feature would you most like to see in a future version of F#?
Mark: I can’t say that I’m missing much. If you go to the F# language user voice forum, you can see various feature ideas for the future of the language, and while I’m voting on some of them, they mostly fall into the nice-to-have category.
At the moment, I’m excitedly learning about more advanced type systems like Haskell’s, so it’d be easy to say that I’d like to have typeclasses in F# as well, but I’m not sure it actually belongs there.
What F# needs more than anything else is better tooling, and Microsoft’s official ‘acknowledgement’ that it exists, and is worthwhile catering to.
Kit: Not a language feature but an IDE feature — the ability for features like go-to-definition and find-all-references to work between C# and F# projects in a mixed-language solution. I would sacrifice any conceivable language feature to have that work perfectly!
Dave: Unfortunately for me, due to team dynamics and now, the nature of consulting work, I’ve spent most of my time the past year working exclusively in C# and JavaScript so I don’t really have anything to add here. I am glad that pipelining to constructors made its way into the language though.
Alena: The most expected feature for me is support for .NET Core and CoreCLR, and that work has already started!
Scott: Actually, I like F# just as it is right now. I know that there is some occasional Haskell-envy from the F# community, but I like having languages with different personalities, and I think simplicity is often under-rated.
I would be wary of adding new features, especially advanced ones, because every upside may have a hidden downside; every new feature has to be supported and documented and could potentially make understanding code even harder. I think of Perl and Scala as warnings of where that can lead.
Sure, there are a few technical things that would make certain things easier: higher-kinded types perhaps, or some simple dependent types. But really, I think that what is most important are non-language “features” such as libraries and the community. There’s a very interesting talk on programming language adoption which has some interesting ideas on this.
So, for F# “feature” improvements, I would pick native support, more libraries, and so on, over language changes.
Mike: Type Classes are the obvious thing that would make the most difference. But apparently there’s almost no chance of seeing them without major changes to the CLR.
Ashic: Higher kinded types, and dependent types.
If you decide to learn F#
Here are some free resources
Scott Wlaschin’s fsharpforfunandprofit.com
Mr Bolognese on Channel 9 — An Introduction to F#
E-books and paperbacks
Scott Wlaschin — Understanding Functional Programming
Tao Liu — F# for C# Developers
Beginning F# 4.0
The Book of F#
Pluralsight (subscription required)
See my Unofficial F# Learning Path
Finally I would like to thank all of the special guests for their valuable advice and cordially invite you to leave any comments that may have below.