Skip to content
11 March 2020

How to choose a programming language for your project? Avoid these biases.

Starting a new project means fleshing out the specifications – a daunting task given all the options. In this article we will share advice that gives you greater peace of mind when choosing a programming language for your project.

We will focus on the backend, as the choice of coding language for the frontend is usually more limited. Most of the advice is equally valid for backend and frontend, though, especially when it comes to the biases we may have.

Launching a technical project starts with a lot of non-technical considerations. Depending on your level of experience in the field, this might appear counterintuitive, but don’t forget that a technical artifact is always created to answer a non-technical need that defines its characteristics.

These are the main things you’ll consider when choosing a programming language.

Development speed

The time required to produce code can be crucial if you want to optimize your time to market. It is usually a tradeoff with robustness, however, as more flexible languages may be faster to code in due to their forgiving nature, but might make you spend more time debugging. The tools offered by the language also have an impact on the speed of writing code.

Execution speed

This criterion depends on your needs more than anything. You may not have a lot of data to process, you may not have to deliver the results fast, you may be bound to third-party applications. If you deploy in the cloud, you may be invoiced by computing time, in which case time literally is money.

Robustness

As said, a robust language may be harder to develop into, but can guarantee a smoother execution. This can be enhanced by external tools such as linters, but we will focus on the guarantees offered by the language itself, such as typing.

Developer availability

The last point is not a technical, but an HR consideration. You can build your application in any language, but should you need to expand the team, replace a team member or fix a legacy project, it is easier to find new developers for some languages than others. But do remember that a larger pool often goes hand in hand with varying quality.

Some of the most widely used languages are evaluated on these criteria in the table below.

LanguageDevelopment speedExecution speedRobustnessDeveloper availability
Javascript+++++++++++
Typescript++++++++++
Python++++++++++
Go+++++++++++
Rust+++++++++++
Java+++++++++++
Haskell++++++++
ReasonML++++++++++

Why do we choose the wrong language?

A time may come when you realize that a project has not been written in the most optimal language, and most of the time this is fine. Choosing a language is always a compromise between benefits and shortcomings. But sometimes the benefits don’t outweigh the downsides, and you end up with the wrong language.

The word “wrong” might feel strong. The purpose is not to make a moral statement, however, but to analyze the factors leading to a specific situation in order to identify different categories of mistakes.

Group effect

I have not always worked in IT and from my perspective, the IT crowd paradoxically seems to have a strong bias towards group effects.

The most famous of these biases is the infamous bandwagon effect. Languages come and go, and we are quite prone to falling for the latest hotness. We are constantly surrounded by “trends”, “developer surveys”, “github stars” and other popularity metrics that guide our decisions.

The authority bias, where we give more value to technologies that are validated by figures we respect, is connected to the bandwagon effect. We might be biased towards Java because our teachers used it, or towards Go because it’s a Google language. But this has no impact on their relative strengths and weaknesses.

The last bias I see a lot in our community is the pro-innovation bias, where we are blinded by the benefits of something new and forget the advantages of older technologies. To put it bluntly, when something new comes out, we are a bit too quick to get rid of the older technology.

Anchoring to the past

When we start a new project we tend to keep using the same technologies as in our previous projects. I see two main biases at work here. The first is anchoring. Our mind tends to stick to the first information we had, so when we start thinking about a language, we usually don’t look very far.

We then usually confirm our choice with the law of the instrument: when you have a hammer, everything starts to look like a nail (which I see as the only possible explanation behind Node.js).

Once we have made a decision, we tend to stick to it even when it starts looking like a bad one. We have an unreasonable bias towards the choices we have made, bad-mouthing the other better options, because it’s just too hard to admit we made a bad choice. This is called a choice-supportive bias.

We will refuse to put to waste the work already done, even if it means that we will have to make double the effort in the future (sunken cost fallacy, or escalation of commitment), only to end up in an unbreakable status quo.

Downplaying the future

The last category I will talk about is mainly centered around a bias called hyperbolic discounting. Roughly speaking, we tend to prefer faster rewards to later, bigger ones. Our view of projects tends to be limited to the time before launch, which we want to happen fast. But we need to remember that the time after launch is longer than the time before, and we risk spending a lot of time on debugging and maintenance if we started with the wrong tool.

So, although Time To Market is an important metric, it should not make us go to production with our prototypes (or proofs of concept). And whatever language we used for our prototyping can always be switched to one that is more time-consuming, but also more robust.

Here is a link to a conference video where the speaker developed an app with Elm, and lost her job due to low maintenance needs.

Further reading: The Pragmatic Programmer, chapter “Prototypes and Post-it Notes“

Nothing is permanent: languages can be mixed and replaced

Armed with this knowledge about your own biases, you can start using a language better suited for your project. Here are two suggestions on where to start.

Early design

If you are still early in your project, you fortunately have more options. First and more radically, you can start coding from scratch, learning from what you have done so far. This can save you from bad design choices as well as from a poor choice of language.

Another option is to rely on a domain specific language (DSL) to express your business logic. That way, you hide your development language under a layer of abstraction, and you can rewrite your interpreter in whichever language you want without losing all the logic you wrote in your DSL.

Legacy application

The term “legacy” is feared by most developers, yet every application becomes legacy as soon as it is put to production. But you can still change its language partly or fully. Such changes should nevertheless be made one step at a time. The first and most popular way of achieving this is to replace microservices, possibly breaking them off from a monolith.

If you cannot break your application into smaller pieces or you just want to replace a single critical function or module, you can turn to foreign function interfaces. Some languages even have a transparent way of doing FFIs by inlining code in another language: you can inline assembly language in C, for example, or Javascript in ReasonML.

Further reading:

Why Discord is switching Go to Rust
The Pragmatic Programmer, chapter “Domain Languages”

Written by

Christophe Riolo Uusivaara

Christophe is our backend software engineer who used to be a teacher before entering the world of technology. We at Qvik love Christophe’s warm presence and his French accent.