Why F# is the best enterprise language

Just to be clear, I’m only going to be talking about so-called “enterprise development”. I’m not claiming that F# is the best for systems programming, or games development, or hobby projects. What’s appropriate for one kind of development objective may well be inappropriate for another. Enterprise development has its own constraints and demands, which I think F# is particularly well suited for.

I’ll start with an important caveat, which is that I don’t think that the success or failure of a project depends on using a particular programming language. Much more critical are things like good communication, clear requirements, caring about the user experience, realistic expectations, and so on. If the programming language really was that important, then there would be no successful companies using PHP, Visual Basic, or JavaScript, and all jobs would require Haskell and Lisp skills!

Nevertheless, having said that, I do think that the choice of programming language has an effect on productivity, maintainability, and stability, and that’s what I’m going to talk about in this post.

The characteristics of Enterprise Development

So what are some the key characteristics of “enterprise” development?

Software development is not the focus of the business

In an “enterprise”, software is generally treated as a tool; a cost center rather than a profit center. There is no pressure to have the latest technology, or to hire the best developers, or (sadly) to invest in training.

This means that being “enterprise” has nothing to do with the size of the business. By my definition, Google does not do enterprise development, while a 50-person B2B company probably does.

This also means that companies that develop in-house software to gain a competitive advantage, like FinTech companies, don’t count as “enterprise” either.

Projects are business-centric rather than technology-centric

The goal of enterprise development is generally to support business workflows rather than to implement a specific set of technical requirements. At the most basic level, typical enterprise software just moves data around and transforms it. This sounds trivial and is often looked down on as not “real programming”.

But business workflows involve humans, and any time humans are involved you will always have complexity. Implementing an efficient map/reduce algorithm or optimizing a graphics shader might be tricky, but possibly not as tricky as some business workflows! This 30-year old quote about COBOL sums it up well:

The bias against the problem domain is stated explicitly in [a] programming language textbook, which says that COBOL has “an orientation toward business data processing . . . in which the problems are . . . relatively simple algorithms coupled with high-volume input-output (e.g. computing the payroll for a large organization).”

Anyone who has written a serious payroll program would hardly characterize it as “relatively simple.” I believe that computer scientists have simply not been exposed to the complexity of many business data processing tasks. Computer scientists may also find it difficult to provide elegant theories for the annoying and pervasive complexities of many realistic data processing applications and therefore reject them. - Ben Shneiderman, 1985

Sadly, enterprise development has never been attractive.

Enterprise projects often have a long life

It’s not unique to enterprise development, of course, but it’s common that enterprise software projects live a long time (if they survive childhood). Many projects last five years or more – I am personally familiar with one that started in the 1970’s – and over the lifetime of a project, many developers will be involved. This has a couple of corollaries:

There is a very interesting talk by Robert Smallshire in which he simulates code generation for different size teams over different time periods. So, for example, after five years, the current team will generally only have contributed 37% of the code.

For a bigger team over a longer period, the contribution % can drop even lower.

Yes, these are simulations, but they ring true in my experience.

Enterprise project managers have a low tolerance for risk

As a result of all these factors, project managers tend to be risk averse and are rarely early adopters – why break something that’s already working?

As the saying goes “process is the scar tissue of organizations”. Stability is more important than efficiency.

However, new environmental conditions occasionally arise which force change on even the most conservative businesses. For example, the newfangled “intranet” and “internet” in the 1990’s scared a lot of people and had a lot to do with the rise of Java and VisualBasic/ActiveX. Here’s what the hype looked like back then:

Less than 10 years after those articles were published, the dominant enterprise programming languages had indeed changed to Java and C#.

Thanks to mobile apps and the rise of the cloud, I think we’re in the middle of another era like this, where enterprises are willing to risk new technologies so as not to get left behind. The challenge of course, is how to adopt new technologies without major disruption.

What is important when choosing an enterprise language?

So how does all this affect choose a programming language and its associated ecosystem, from a project manager’s point of view?

It should be enterprise-friendly

A project manager is not just choosing a programming language, they’re also committing to the ecosystem around the language, and the future support for that ecosystem. As noted above, enterprise development is not about being on the bleeding edge. Rather, if the ecosystem has support from an enterprise-friendly company like Microsoft, Oracle or Google, that is a big plus.

Also, from the enterprise manager’s point of view, it’s critical that the language and its ecosystem have deep support for enterprise databases (Oracle, Sql Server), enterprise web servers, enterprise authentication (AD, LDAP), enterprise data formats (XML) etc. It’s unlikely that support for the latest hotness will be their primary concern.

It should be future-proof

Given the longevity of enterprise projects, we want to make sure that the ecosystem and tooling will still be around and supported in, say, 10 years. If and when new platforms come along, you shouldn’t have to throw away all your code.

It should be flexible

And if you’re going to commit to an ecosystem, you’d ideally want to use it in as many different situations as possible (e.g. desktop apps, server apps, web apps) and different target platforms (Windows, Mac, Linux, mobile, etc).

It should make maintenance easy

Since the members of the team will probably rotate over the lifetime of the project, and most code will not be written by the current team, the dominant concerns are things like:

Choosing an enterprise language, part 1

With these requirements in place, we can use them to reduce our language choices.

So, far no surprises. We have come up with the usual suspects, Java and C#.

If this was 2008, we’d be done. But it isn’t, and we’re not. In the last decade, there has been an explosion of new languages which are strong contenders to be better enterprise languages than C# and Java. Let’s look at why.

The rise of functional programming

Functional programming is the new hotness right now, but regardless of the hype, most modern programming languages are introducing FP-friendly features that make a big difference to software quality:

If we look at languages which support these features, we end up with the mainstream statically-typed FP languages (Haskell, F#, OCaml) and the more modern FP-influenced languages: Swift, Scala, Kotlin, Rust, TypeScript, etc.

As I said above, the rise of new technologies such as serverless means that enterprises will be willing to switch to these FP-influenced languages if they can provide a competitive advantage (which I think they do) and if the switch can be made with minimal disruption (which depends on the choice of language).

The danger of too much abstraction

Some FP languages (Haskell and Scala in particular) support some features that allow high levels of abstraction. Some people like to quote Dijkstra here:

“The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise” – E.W. Dijkstra

That’s great, but I believe that in the specific context of enterprise development, too much abstraction can cause problems. If used too freely, it requires that all developers working on a project need to have the same understanding of the “new semantic level”, which is a burden on training and employability. All it takes is for one person to have too much fun with category theory in the code, and the code is rendered unmaintainable for everyone else.

That is, just as you can shoot yourself in the foot with low-level features, you can also shoot yourself in the foot with high-level features as well. For an enterprise language, we need to trim the top-end of the language capabilities as well as the bottom-end, and encourage an “only one way to do it” approach as much as possible.**

So I’m going to penalize Haskell and Scala at this point for being too easy to abuse.

** One of reasons people like Go or Elm as languages is because they are restrictive. There is a standard way of doing things, which in turn means that reading and maintaining someone else’s code is straightforward.

But how much abstraction is too much?

Are generics too advanced? 15 years ago, perhaps. But today it’s clear that it’s a mainstream feature. (The golang designers disagree!)

But how about lambdas? How about monads? I think that most FP concepts are on the verge of being mainstream now, and in ten years time will be commonly accepted, so it’s not unreasonable to have a language that supports them.

For me, in 2018, the “just-right” level of abstraction is that found in ML languages like OCaml and F#. In 10 years time things may be different, and we may be able to adjust the acceptable level of abstraction upwards.

However, I’m not convinced that more abstract, mathematical style programming (a la Idris, Coq) will ever be commonplace in the enterprise, due to the variation in employee skills. Yes, this could be solved with better training, or a certified-software-engineer qualification, but I’m not holding my breath.

Choosing an enterprise language, part 2

If we then filter these newer languages by the “enterprise” criteria above we end up with the FP-influenced languages that support .NET and the JVM, namely:

To summarize the “why not language X” objections again:

What about higher-kinded types? What about type classes? What about GADTs?

Oh dear, none of the three finalists support them right now. I’ll let you judge whether this is a deal-breaker for enterprise development.

Picking a favorite

The three languages left (F#, Kotlin and TypeScript) are all good choices, they’re all open-source, cross platform, and enterprise friendly.

If you’re already using the JVM, then obviously Kotlin provides the best migration path. Similarly, if you’re using Node on the backend, then TypeScript is good (although trusting npm packages might be a problem).

But if you’re doing greenfield development (or if you are already on .NET) I believe that F# has the edge (and this is where I might be a bit biased!)

Of course, Kotlin can do some of these things and TypeScript some of the others, but I think that F# has the most breadth overall.

Extract from ScottW's note:

Discover how we can help you

Please leave us your question and one of our assistants will contact you asap.