I've personally worked with many teams and organisations over the last few years, helping them adopt F# - some more successfully than others. Having spoken to more and more people who need help understanding how to successfully adopt F# (and, importantly, what doesn't work), I thought that I would put down some thoughts and experiences that I've observed in this time. As this post has grown, I've decided to split it into three parts in order to make it more digestable.
The Three Stages of Adoption
When helping teams adopt F#, the request often comes from two distinct sources:
- Top-down - CTO or delivery lead etc. has made a decision to adopt F#. Now they have the challenge of getting by in from a sometimes-sceptical development team - or perhaps colleagues at the senior management level etc.
- It also equally often comes from the ground up: Developers, who have the task of not only convincing colleagues but also getting buy-in from management.
In both cases, these individuals are what I classify as an "enthusiast" - one of three stages of F# adoption that I have over the years identified:
1. The Curious
Someone that is curious about F# may have heard of it, or perhaps watched a video or two. Maybe they've even attended a user group or conference and seen a talk on it. They're somewhat interested in F# and think it sounds cool, but aren't sold on it. Generally, they simply don't see the benefits of it, in tangible terms, that would warrant the cost and effort of further investigation. They need some incentive to try it out.
2. The Enthusiast
The enthusiast has started using F#, but not as a part of their day-to-day job. This may include hobby projects, or lunch-and-learns etc. Perhaps they have an open source project that they contribute to. They may blog about F# and are often active on social media forums etc. These are people that are already sold on the benefits of F#, but are unable to use it in their organisation because of several reasons (many of which I'll cover in this series). Some of these are factors that the Enthusiast has control over, whilst others are on the edges of their scope of influence.
3. The Adopter
These individuals have already adopted F# in their organisations; there is no taboo about using it, and they are comfortable using F# in their teams without needing to justify it from those higher up the decision chain.
I'll be covering how to move from being Curious to an Enthusiast in future posts.
Moving from Enthusiast to Adopter
Even when there's no specific blocker for adopting F#, enthusiasts often fail to make that leap to gain adoption for a number of reasons. Usually, there are one or two developers that are sold on F# and want to use it within their team; the challenge is explaining and demonstrating the value to the rest of the team, and (of course) whoever is responsible for supporting the decision - and this is where they fail.
For those of you who are reading and found yourself relating to this, read on: the remainder of this article is about how to best maximise the chances of your being able to adopt F# in your team.
Although I covered the two "sources" of Enthusiast above (CxO and developer), I'm going to focus mostly on the developer perspective today. Many of these techniques can be equally applied coming from the top-down as well.
The causes for not getting F# adoption "over the line" can vary from something as simple as not thinking to ask (or not asking the right people) to having a team that are simply not interested, to not being willing to make any personal investment into the exercise, to failing to successfully deliver and the team reverting to whatever they were using before.
Try to identify why you've not been able to get F# adopted. Who blocked it? What were their concerns?
Here are some common reasons an Enthusiast fails to convince others:
- They are unable to formulate the rationale to their colleagues and management to make the move worthwhile.
- They do not yet have the confidence or experience to stake their personal reputation on F# - or at least, they don't want to be the only one doing so.
- Tools and processes weren't put in place to ensure a successful transition
- They work in an organisation where they are inherently coupled to their current development language / environment. For example, perhaps they are a Python library vendor. Or are writing code that is specifically tied to C# (note: although I hear this reason quite often, in reality it is rarely the case).
- The benefits of transitioning is simply not felt to be worth the effort; perhaps the feeling is that the perceived risk of adopting F# is too high for several reasons.
- It's bad timing. The team are late on the current project and everyone is flailing around trying to meet the next unachievable deadline.
Whilst you can't gurantee success, I would suggest that there are three elements to at least maximising the chances of getting F# adopted:
- Planning: Putting in place a realistic plan for evaluation and adoption
- Pitching: Making the case for F# to the right people at the right time in the right way
- Executing: Ensuring that you have the right processes and practices in place to give you and your team the best chance of successfully using F#
In this post, I'm going to focus on the first of the three elements.
Planning the move
Before you make your empassioned plea to your boss talking about monads and computation expressions, spend some time putting together a cogent plan that shows you have considered the costs and benefits and have a realistic strategy for testing whether F# is going to work in your organisation. Ironically, despite this being critical to adoption, it's the one that people rarely spend sufficient time on, yet the likelihood of successful adoption is clearly affected - at least in part - but putting some time up-front into formulating a basic strategy.
1. Make a plan!
You would be surprised the amount of times people simply forget to put some kind - any kind - of plan together.
- What's the end goal you have: Moving the entire department to F#, or just a specific team or technical area?
- How long do you expect it to take?
- How will you get there? Will your hold team stop using whatever language you're using today and switch the next day to F# (hint: don't do this!) or will you adopt a phased approach of some sort?
- What costs are there involved e.g. training or extra software?
Write it down in either a Word document, OneNote or similar - anything to record the different aspects of the plan, which you can then move into a proposal of some sort.
Demonstrating that you've considered elements like this will go a long way to getting people to take you seriously, as it shows you've thought things through.
2. Document the use case
Where do you see F# being used in your team? As a full replacement for whatever language you're using today, or as a niche area that fulfils a specific gap? Do you see F# as a low-risk, low-cost tool that just one or two people will be using, or as a long-term plan to migrate across the whole team? Or something in between - or a phased approach whereby you start using it "around the edges" and then move onto more amibitious challenges?
Be aware of this, and plan the rest of your strategy accordingly.
3. Don't do it alone
See if there are any other colleagues in your team that are equally enthusiastic about F# - or even have experience using it in production. They might not only have other ideas that you have overlooked, but two or three people all saying the same thing carries a lot more weight than a single developer.
Team leads and management want a happy team; if only one individual is proposing F# and other developers in your team are not yet sold, this will only instil doubt: your manager will wonder why aren't the rest of the team also sold on this? Worse still, they won't want to risk disharmony by pushing something on others that they know people aren't excited about.
Get others on board, and the chance of adoption will greatly increase.
4. Have realistic expectations
Don't expect to rewrite your entire application in F#, nor write the next ten-developer greenfield app entirely in F#. Start slow, with a realistic yet challenging plan. Avoid something that is so simple that it doesn't show off the power of F#, yet be wary of putting in a massive, high-risk project that could blow the whole endeavour. Lower risk means a higher chance of your colleagues and boss accepting the proposal - if it doesn't work, it's probably not going to cost them their job.
Also, consider the timeline: if you or your colleagues will need time to upskill, how long do you predict it will be until your team start to see the return on investment? A week? A month? Six months? Again, don't sugar coat this - there's no point saying that the entire team will have cross-trained into F# in 3 days if you really believe it's going to take 3 weeks.
If you're thinking in terms of a "full" migration to F#, whilst you often will have some low-hanging fruit when moving to F# - scripts, data analysis, validation etc. - don't just frame it in terms of "quick wins". Instead, discuss how your team are making a conscious decision to strategically shift to using and benefit from functional programming. This is a longer term goal, but the benefits will be that much greater.
5. Set up clear measures
Come up with ways that you can measure the success of the project - define what "good" is. This may be simple metrics such as number of reported bugs, or time required to develop features / tracking velocity, or could be feedback forms for colleagues to describe their levels of satisfaction and enjoyment.
6. Decide on an integration strategy
If you're planning on working on integrating F# onto an existing solution, consider how you'll do this. A couple of ways I often recommend are horizontal and vertical slicing. With horizontal slicing, you pick a horizontal tier in your stack that all layers of your application must go through. This could be e.g. a data access layer, or something more cross cutting such as a validation library or caching module. Conversely, a vertical slice proves that you can use F# end-to-end, from front-end to database and back again.
- Horizontal layers impact across the whole application - all features rely on them, and you have to consider interop with the rest of the system, but from the F# perspective you won't have to become an expert across the whole stack.
- Vertical layers mean you don't have to interoperate with any of the rest of the system, but you'll need to learn to do F# equivalents across the whole stack. Depending on the complexity of your application, this may be tricky.
If you see F# as more of a "utility" tool to support your main codebase, consider what those applications will be and how you'll implement them. Build scripts? Azure deployment pipelines? Testing? etc. I often see people suggest these as good "low-risk" ways of trying out F#, and this is true, but beware that this runs the risk of F# being shoehorned into the "edges" of your application and never considered as a language that can (and should) be used at the core of a codebase.
7. Have a fallback plan
Even though you may be confident of success, not everyone will be. De-risk the proposal by having a fallback plan in case things go pear-shaped. For example, you could consider a "parallel" stream that delivers the same features that you are doing in your regular language / environment. Or you could suggest that you'll review on a regular basis and if things aren't looking good at a certain milestone, you'll pull the plug and go back to how you used to do things. Or pick something that is not on the critical path - if it doesn't work, you'll have lost some development time and money, but you won't have held up the whole show.
Demonstrate that you've considered failure and have a plan for dealing with it, however unlikely you might think it is, and you'll find people will take you much more seriously.
8. Consider a proof-of-concept
Another way of getting up and running is to suggest a completely standalone proof-of-concept. Perhaps this is for a new project you might be starting in a few weeks, or a rewrite of an existing module - something that you know inside out from a business point of view; the benefit of this is that you can compare and contrast the current and new approach with a common understanding.
Depending on your time, you could even consider doing this sort of proof-of-concept in advance of your pitch, as a fait accompli - in other ways, demonstrate something that you've already gotten working. This can be a very effective way of proving F# and dispelling FUD (fear, uncertainty and doubt), if you have the time and opportunity to do.
8. Get external feedback
Speak to someone who has successfully (or not) adopted F# before. Get their feedback on your plan, and see if it holds up. They may have personal experience that could prove useful for you! As an example, we offer free one-to-one sessions to help ensure that you do things the right way to maximise the chances of success.
9. Be committed
If you believe in F#, show it. Don't be arrogant, but there's nothing wrong with showing that you believe in F# and are confident that it will help your organisation. Show that you're committed to seeing this through, and this isn't simply a passing fad that you're going to abandon in a few weeks' time.
10. Don't do it via the back door
I know a few people who have actually had some success with this approach: essentially, making a plan but not telling anyone about it but a few developers in secret. Be very, very careful of this approach. On the one hand, it shows you're willing to walk the walk. But, unless you have a very trusting boss, they probably won't appreciate your having done this behind their back - and worse still, if for whatever reason it doesn't work, it'll come back straight on you.
Summary
We've looked at some of the considerations when planning how to adopt F#. On the one hand, if you have the belief in F# you may wonder why you need to bother with this at all. But getting others on board, supporting and working alongside you will lead to a much greater chance of adoption - and putting a plan in place is the first step in that.
Next time out, I'll discuss pitching F# to colleagues, including what to say, how to say it, and classic mistakes to avoid. Until then, have (fun -> ())
.