On Choosing Programming Languages

Nikolay Nemshilov
Compono Engineering
11 min readJan 13, 2019

--

It is tempting to start this article with the classical “i wanted to write this for so long”, but the truth is, pretty much every single software developer on this planet did; many multiple times throughout their careers. The problem of choosing a programming language is as old as programming languages themselves, and I wouldn’t cover the entire topic even if I knew how to. All I want to achieve here is to convey a bit unconventional way of looking at the problem.

Before we go, a fair warning. I’ve been doing this for 20 years now, and I might sound a bit cynical here and there. I’m perfectly aware that some people tend to be sensitive to the subject, and so, if you elect to feel infuriated by what I have to say, please know I won’t hold it against you.

Okay, now that I have your guard raised sufficiently high, and you’re ready to take what I have to say with a grain of salt, lets dive into it!

The Myth of a Better Language

At the center of all the discussions about programming language comparisons lies the idea of a better programming language. It is not a problem on its own—after all, if you set on improving something, you are by the definition meant to produce something better. And programming languages are not exception.

The problem raises when one needs to turn the results of their hard work into a significant market share. Unfortunately, there is no practical difference between selling detergent and selling programming languages. You go through the same motions, you find a differentiating factor — real or imagined — , you boost it up, and you occasionally say or imply unflattering things about competitors to polarize your audience. Here are some examples, anything sounds familiar?

1. Programming language that scales
2. Programming language that prevents bugs
3. Programming language that is simple to understand
4. Programming language for nice people
5. Practical Programming language

The net result of those efforts is that the idea of a drastically better programming language is planted firmly in our heads from the very early age. And, as such, many of us deeply believe in this idea of fundamental differences between programming languages, which we then use consciously and unconsciously every time we have to evaluate anything about our beloved or despised languages.

I know this will sound a bit harsh, but in a sense, mechanically, it works the same way as some people’s believes in drastic differences between human beings. Instead of race, religion or nationality, one deals with programming language families, static vs. dynamic typing, memory management, etc. Once you believe that there are innate differences, and you have your preconceptions of what’s better, you will apply those as a confirmation bias to everything you look at.

The thing is though, programming languages are like human beings, they compete on a shared open field. There are differences, but they are not innate, they are contextual and in the grand schema of things one can hardly tell what’s right or wrong. All languages you deal with are turing complete, they all basically transform one state into another and hence have the same instruments: data structures, conditions, operations and memory traversing mechanisms.

All programming languages are engaged in a continuous arms race and use the same shared resources. They constantly morph and borrow from each other. As the result, there is as much differences between programming languages as there are differences between brands of detergent. It’s mostly about what appeals to you emotionally that matters. More on this later.

The Myth of an Objective Measurement

To cut through the marketing noise, most of us turn to data. It is the same old question we ask ourselves: “how can I make a better decision based on objective measurements?”

The flavours of the “data” usually range from “what does company X use?”, to “what does scientific research say?”, to, eventually, “how much a developer who works with language X paid?”. All very good questions, but none has anything to do with the quality of a language itself.

“What company X uses”, has astronomically little to do with the company’s success. Finances, company culture, business opportunity, process management and access to talent account for 99.99% of the company success. Which language they use is mostly an accident of the early founder’s preferences. Google -> Java, Facebook -> PHP, Uber -> Node/Go, there is hardly any consistency between language choices and company success. Moreover, there are no big names that started with languages that are considered superior, Haskell, Rust and such. Don’t you find that a little bit strange? You should.

“What does scientific research say?” is misleading too. Firstly, there is no obvious or even convenient way to measure programming languages for the purpose of an adequate comparison. And so people dive into all sorts of reductionist ways to look at the problem, measuring things like “bug density”, complexity and such, here is an example. Secondly, programmers are notoriously bad at interpreting statistical data. You know what Nietzsche used to say “when you stare into the abyss long enough, the abyss starts to stare back at you”. And so people start to rage about the broken promise of static typing and similar click bite nonsense.

Here is a classical example, look at the table of bug density coefficient below and compare PHP vs. JavaScript:

Most of people will look at 0.10 for PHP and 0.03 for JavaScript, and conclude that PHP is 3 times more error prone than JavaScript. It seems like an obvious conclusion. But the truth of the matter is that PHP developers commit 99.90% of correct code and JavaScript developers commit 99.97% of correct code. Not so drastic anymore isn’t it?

Notice how I said “PHP developers commit”, not “PHP language commits”? That is because research into programming languages without taking into an account people who use them is a penis measurement contest in a nut shell. You cannot take Closure code, written mostly by Java veterans with 5–10 years of experience, and compare it to JavaScript where more than a half of the developers learned jQuery as their first “language”, and then draw any sensible conclusions from that. All you are going to end up with is a cheap drama.

Which brings us to the main point of this rant.

Personality Types, Actually

This is the area people very rarely touch when they talk about programming languages. And the more I live the more I start to believe that this is actually the underwater part of the iceberg. Technology people are notorious for taking this weird pride in being oblivious to understanding humans, so let me throw a very basic structure into the mix.

Probably everyone is aware of such types as introverts and extroverts? We all took the test at some point, and know our own types. What people often don’t know is that introverts vs extroverts is not a binary option. It’s a continuum. For example, I am in the middle of the scale and can land on either side depending on the context and how well recharged I feel at the moment of a test.

Like extrovert vs introvert, there are other dimensions to a human personality type. There are a lot of systems that try to mix and match those dimensions into traits that describe a personality. One of the more known is called Myers-Briggs Personality Types System. But there are others, such as the five-factors model, OCEAN, the standard model, etc. Point being there are some very interesting personality aspects that affect your decision making and preferences. I’ll touch on a couple of them

Practical vs. Abstract — this is one of the more broad dimensions. Basically this draws a line between people who are focused on practical details of what is, and people who operate in the realm of possibilities and focused on the big picture thinking and what could be. When it comes to programming languages this will induce two types of preferences: some people will want to see an easy to grasp story in ones code, basically, how readable it is in terms what the code does; and others will be focused on abstractions, interfaces, and data flow patterns. Think Python or JavaScript vs Java.

Uninhibited vs Controlled — describes how people perceive order. Some people are more creative and need the freedom to move quickly and change things easily. Others require structural rigidity, they need to feel securely bolted down in their own shoes to be effective. The classical examples here would be statically vs. dynamic typed; or functional vs. imperative languages.

As you can see, when it comes to decision making, we all think differently. In simple terms one could say there is a gradient going from practical and uninhibited to abstract and controlled. As the result, a context (language/toolset) that feels right for one person might feel completely wrong to another. But because we, software developers, not accustomed to think in terms of feelings and emotions, we prefer to elevate them to the realm of language features, self-assign values to those features, and then justify our choices from this self-righteus perspective.

Group Dynamics

The interesting thing about us humans is that we all want to be loved and fit in. And the easiest way to do this is to belong to a group of like minded people. As the result, those groups usually form around the same “values”, which are derived from prevalent personality traits.

Historically, programming languages came from academic circles, which, for the sake of the argument, we could label as abstract and controlled; because those individuals used to deal with science, math and equations on a daily basis. As software engineering became a profession and available to a broader audience, the groups moved towards more practical and uninhibited. One could track this change via popularity of programming languages.

ASM -> C -> C++ -> Java -> Ruby/Python -> JavaScript

The reason for this happening is that personality traits are not distributed evenly among the population. Superior abstract thinking skills are actually rarity, and majority of people think in more practical terms. The same goes for the sense of order, most people prefer to embrace the chaos rather than try to classify everything into structures and categories, and try to control uncertainty this way.

As the result, we all can sense the gap between languages popularity that is driven by unevenly distributed traits, and our own personality types. Some of us are more flexible and polyglothic, and can fit into most environments; or simply belong to the prevalent types. But, some are more rigid and require a better tools/personality fit. Which, thanks to the marketing materials we consume, is not always so obvious. And so we cave into the peer pressure and try to search for the problem in ourselves rather than trying to understand the reasons behind the mismatch.

Conclusions

I think that choosing a programming language can be a rational and analytical decision, if you want it to be. But one should look at this decision in a similar way one looks at choosing a company they want to work for. Forget the language and technology, look at the people, the community, you’re going to work with. Do you click with them? Are you okay with becoming one of them? Does it actually fit your personality?

Remember that marketing material is your enemy here. Often times the authors of a language will try to infer value from technical characteristics of their language. This is not how values work though. Values can only be derived from a culture, and culture is derived from personalities.

In the end, your effectiveness as a software engineer will depend on how well you fit into a culture associated with the community around a language, not the features a language has.

After all, majority of your time as a software developer doesn’t actually go into writing code. Most of your time goes into figuring how things work and how to express that in code. This is the part where you need to reduce friction the most. And this part depends on how you make sense of the world, which is largely driven by your personality type.

PS: A Case Study

I feel like it would be unfair to leave you hanging here with just an idea. So, I’ll try to use myself as an example to demonstrate the point. I worked professionally with a good dozen of languages throughout my 20 years career; some worked better than others, and a lot of this can be explained via my personality traits.

Hi, I’m Nikolay here are my personality traits:

I’m an omnivert: 49% extrovert and 51% introvert
I’m a bit on the creative side: 60% uninhibited and 40% controlled
I’m fully abstractical: 50% practical and 50% abstract
And I looove change: 90% driver and 10% resister

I started with C and didn’t particularly like it. I felt it was lacking abstractions and structure to properly express the meaning behind my code. I moved to C++, loved the classes, couldn’t stand the messy types system.

Then I moved to Java, loved the consistent abstractions and types system. Didn’t like the lack of practicality. It felt too slow and to rigid. Worst of all I didn’t like the community for being too far on the abstract side of thinking. One couldn’t sneeze without involving 5 software design patterns.

Then I moved to Python and PHP. Loved the practical community. Hated lack of consistent types system and general concern for good abstractions. One could do it, but good software design wasn’t in the community/language DNA.

And so I moved to Ruby, which is also very practical, but the language also has a solid and consistent types system; albeit a dynamic one. The community revolved around the idea of taking the best from Java/Smalltalk and make it more approachable and practical. Ruby was my favourite language for good 10 years. I eventually left for two reasons. I crave change and the language was falling behind, and I found it hard to fit into the white middle-class american-ish dude community that formed around Rails.

Then I moved to a full-time JavaScript environment, which fed my craving for change and diversity for years. Thanks for ES6 it is fairly well structured and consistent, and practical to the bone. The awesome thing about JavaScript to me is that thanks to the huge number of people using it, the language and tooling is heavily optimised to solve real life problems. I missed good abstractions and software design though.

Eventually I found myself with TypeScript (actually I would prefer Flow, but the thing is dead unfortunately). I find it both practical — thanks to the JavaScript bones — and abstract thanks to a solid types system. TypeScript is still flexible enough to solve real life problems with ease, and it has just enough typings to satisfy my need for control over madness. And finally, thanks to the JavaScript ecosystem, I can enjoy the crazy pace of change in the technology.

TypeScript ticks most of my boxes pretty closely, but I know it doesn’t have to be TypeScript. Any language that is in a rapidly changing environment, that provides a good practicality and abstraction balance, and allows me to write simple and flexible code will do. Swift is great. Go is pretty neat too. The important thing is that this is my own personality preferences, for someone else this could be a different set, and that is fine too.

I hope this will clarify the point of view i’m trying to convey.

--

--

Nikolay Nemshilov
Compono Engineering

Engineer, obsessive maker, and occasional speaker. CTO at @shortlyster