One of the first decisions one has to make when learning to program is which programming language to learn. In some cases, the choice is made for you, dictated either by the language used in a class, or by a framework you need to use, but often you will have at least a few options.

Picking your first (and second) language can be daunting, as there are so many candidates out there. It’s not always clear how they differ, and much less which are “better” for what you are wanting to do. This post will try to give a high-level overview of the choices that are available, and what differentiates them, to aid you in making an informed decision.

Note that this post is not a review of any of these languages, nor does it aim to find the “best” programming language out there. I will describe different types of languages, and give examples for each one, but the choice of category, and language within that category, is yours. My hope is that this post will provide you with enough context and terminology to let you continue a more informed and restricted search on your own.

Choosing a language

Programming languages generally belong to a number of different categories. These are often referred to as “paradigms” in the literature. As we’ll see shortly, the lines between different paradigms are often blurred, especially when it comes to more modern languages. Many languages are so similar that they differ mostly in syntax, ecosystem, and conventions, not in features. Nevertheless, they can be useful for limiting the number of languages to look at in more detail.

Through all of this, it is important to keep in mind that these languages can all do the same things — they all let you print to the screen, do math, read files, connect to the internet, etc. They differ in how they enable you to do that, and in many cases, how convenient it is to do those things. Some languages are more suitable for doing statistical computation, some are better for building websites, and others are better for interacting with hardware. This is part of the reason why it’s important to ask yourself what kind of thing you want to do first, and only then start looking for a language.

Level of abstraction

Let’s start with one of the most discriminatory features of programming languages: the level of abstraction from the hardware. Languages that hide more of the inner workings of the computer from the programmer are usually referred to as “high-level”, whereas those that expose these low-level details are called “low-level”. This distinction is more of a scale than it is a categorization — plenty of languages can be considered “mid-level” in terms of abstraction.

In general, abstractions come at a price, and the higher level the languages, the lower the performance. That said, even high-level languages have performance that is suitable for most applications. You should find a language in the “highest” category whose performance your application can tolerate.

Increased abstraction also hides more of the inner workings of your program from you — there’s more “magic” going on behind the scenes. This is often what you want, as it can save you a lot of typing, but it may cause frustration if things break or underperform, and you have to figure out why. How much magic is right for you is a matter of personal taste, and you may have to play around with multiple languages before you find what’s right for you.

Without further ado, let’s look at a few different “tiers” on this scale, and examples of what languages fit in each tier.

Strictness

Finding the right level of abstraction usually takes you a long way towards picking a language. This is particularly true as many of the languages within each tier are fairly similar in terms of features, and mostly vary in syntax. Nonetheless, it can be useful to have a second scale on which to evaluate different languages within a tier. I have often found it useful to compare languages in terms of their “strictness”. Stricter languages are harder to write code for, as they require you to convince the compiler that your code adheres to some notion of “correct”, but once your code compiles, you can be more certain that it does the right thing. Conversely, less strict languages place fewer restrictions on your code, but your programs are more likely to break when you run them.

So, in order from less to more strict:

Does it matter where I start?

If you just want to learn how to program, with few or no use-cases in mind, it can be hard to pick any of these categories. If you’re in this position, you should ask yourself what you’re more interested in learning. Starting with a lower-level language will force you to learn more about how the computer’s CPU and memory works, which provides a solid foundation on which to build if you want to make things go fast, if you want to build something like an Operating System, a device driver, or a resource-intensive game. On the other hand, starting with a higher-level language will let you dive right into algorithms and data structures, without worrying too much about the low-level details. This might be what you want if your background is more math-y, or if you have some problem you’d like to solve quickly (e.g., data analytics, small convenience tools, or a website).

Switching languages

The descriptions I’ve given above will hopefully help you make a good decision about what language to dive into. Inevitably, however, you will find that the language you picked doesn’t work very well for some particular task, or that there’s something that irks you about it. When this happens, don’t be afraid to try out another language! In many cases, you will find that the new language differs from your current one mostly in terms of syntax, especially if you are switching between languages of a similar level of strictness and abstraction.

Switching to languages that are “farther apart” is harder, as there are new concepts you need to learn. Luckily, much of your existing experience will translate easily — notions like variables, strings, functions, modules are found in almost all languages. Furthermore, the more languages you know, the easier it is to learn new ones. This is one of the reason experienced developers often claim that they know dozens of languages; each additional language becomes easier to learn. In many cases, learning a new language can even change the way you program in the languages you already know! Picking up another language, or sampling a bunch of them, is a natural part of developing yourself as a programmer — don’t be afraid to try!

Good luck, and don’t be too stressed about the decision. Especially in the beginning, everything you learn will come to good use, even if you later change your mind.