In a recent blog post about null reference exceptions, Don Syme bemoaned the status quo:
Unfortunately a sort of stasis, or lack-of-will seems to be gripping the industry at the moment. People stick with their existing languages, though occasionally make noises about needing non-null types (thus making C# and Java even more complex, when we should be ridding ourselves of this curse altogether).
So why do people stick with their existing languages, and what can we do to increase F# adoption? I think it is useful to start by considering what someone faces when they decide to investigate F#. They will find very useful material online, covering a range of topics, and after a little browsing will find themselves faced with a barrage of concepts:
- Expression-oriented programming
- First class functions
- Higher order functions
- Pattern matching
- Discriminated unions
- Partial function application
- Recursion instead of loops
And how do people react when faced with so much information? Switch, a book by Chip and Dan Heath, provides some answers and, as the subtitle suggests, provides ways to tackle this kind of problem. In it the authors make the point that effecting change requires not just rational arguments, but also emotional arguments and adapting the environment of the target audience.
As engineers, we tend to focus on the rational, and therefore often ignore factors that could have a larger impact. Indeed, there are a wealth of good online articles making rational arguments for wider F# adoption, and yet uptake is not as large as we’d like.
Maybe it is time to take a deep breath and dive into the uncomfortable world of emotional arguments and environmental manipulation?
I think there are three concepts from the book that are applicable here:
Shrink the Change
Coaches are masters of shrinking the change. By pushing…to attain a sequence of “small, visible goals”, they build momentum…A small win reduces importance (“this is no big deal”), reduces demands (“that’s all that needs to be done”), and raises perceived skill levels (“I can do at least that”). All three of these factors will tend to make change easier and more self-sustaining.
We need to reduce that mountain of information into a manageable molehill. I think that involves under-playing the host of benefits and instead focussing on just one or two. We can emphasise that first class and higher order functions are at least somewhat familiar via LINQ. And we can tackle just one of the new concepts at a time – perhaps non-nullability because everyone understands the problem and therefore will understand the benefit of eliminating null references.
I’d also suggest further shrinking the change by encouraging people to start with a single component in F# rather than a full system. However, the interop with other languages weakens the non-nullability argument, so we need to be careful.
Script the Critical Moves
Change brings new choices that create uncertainty…that yield decision paralysis…Change begins at the level of individual decisions and behaviours, but that’s a hard place to start because that’s where the friction is. Inertia and decision paralysis will conspire to keep people doing things the old way. To spark movement you need to provide crystal-clear guidance. That’s why scripting is important…
The barrage of concepts listed earlier is what leads to decision fatigue. To prevent this we need to carefully script the exact steps people should take. So, sticking with non-nullability, we need to show exactly how the single component could be developed to avoid null references. And we need to be specific about how to tackle interop with “dirty” code e.g. how to use the interop features in FSharpx to convert nulls to Options.
Shape the Path
…Alternatively, you can simply make the journey easier. Create a steep downhill slope and give them a push. Remove some friction from the trail.
Anything that gets in the way of making a change, even if it only constitutes a small obstacle, will reduce the likelihood of the change being adopted. Therefore anything we can do to remove the obstacles will be beneficial.
A recent InfoQ survey asked the question “why are you not using functional languages?”, and the top two answers are revealing:
- Couldn’t find developers (770 votes)
- Insufficient tool support (618 votes)
The first reason is a chicken-and-egg situation, so we need to find a way to increase adoption within the developer community – that is the topic of this post. The second reason is more interesting. It specifically mentions automated refactoring support, and that is certainly an area where F# is weak. I’ve heard the (rational) argument that refactoring tools aren’t as important for functional languages, but we need to forget about whether the argument is valid: if there is a perceived tooling problem, then adoption will be adversely affected. This is a case of us failing to “Shape the Path”.
A Crazy Idea
Refactoring tools are extremely hard to write, and require a level of dedicated resource that mean it is unlikely to happen as a spare-time effort, so should we instead start a community-lead fund-raising campaign (Kickstarter?) to pay for the initial development? I can imagine that certain companies would be glad to publicly sponsor such an effort, and that individuals would chip in too.
In order to increase adoption of F#, we need to make the change seem as small, undaunting and easy as possible. The first two can be tackled through tutorials that focus of explaining, in detail, how to achieve a specific benefit. I think the benefit to address is non-nullability, but I’d be very interested to hear other ideas.
A big hurdle in making adoption as easy as possible is lack of tool support. Here I think the scale of the task means we need a more radical approach. Is there sufficient interest, and is the community large enough, to fund such a project?