I hear the question all the time. “What programming languages should I be learning?”. I’ve asked this question many times myself in the past. When you are first getting started programming, it seems like all there is to becoming a good programmer is the number of programming languages you know. Several years later and I now realize this is not the case. If you really want to become a better programmer, instead of focusing on learning more programming languages you should focus on the other aspects of programming.
What it Means to Learn a Programming Language
There are many different pieces to a programming language you have to learn before you really know the language. For the purposes of this post, I will separate them out into two different categories:
Language Syntax: Every language has it’s own way for writing if statements, for loops, function calls, etc. Obviously you need to be familiar with how to write these constructs before you can be proficient in a programming language. Although learning the syntax of a language largely means ingraining the syntax into muscle memory, knowing the syntax for a language is still a necessary step in learning a programming language.
Language Concepts: Beyond the basic syntax of the language, every programming language has it’s own features and concepts that separate it out from other programming languages. Python has constructs such as decorators and context managers. Lisp based languages provide code generation through macros as a first class feature. As you learn a programing language, you become aware of these features the language provides. You learn what each of the features do and how to use them. The cool thing about learning more concepts is that it teaches you new ways to approach problems, but more on that later.
The Benefits of Learning More Programming Languages
As I see it, there are two main advantages to learning more programming languages. First you have the advantage of being able to quickly ramp up on any project that makes use of a programming language you know. If you know Python, you can start contributing to a codebase in Python almost immediately. While this is an advantage for programmers that know more languages, it is only a slight advantage. Usually it takes just a few weeks for a programmer to become proficient at a new programming language. If this is the reason you want to learn so many different programming languages, it makes more sense for you to wait for there to be a project you want to work on that actually forces you to learn a new language as it won’t take much time to ramp up anyways.
The other, more interesting advantage to learning more programming languages, is that each new language will introduce you to new ways of approaching problems. This is mainly because as you learn a language, you learn the specific features the language provides and how to use them to approach problems. In a way, learning a new language “stretches your mind” and allows you to think about problems in new ways. As an example, if you learn a Lisp derived language, you will learn about how to use code generation to approach problems. In the future, being familiar with using code generation allows you to recognize when code generation is the best approach to a problem. As you learn more programming languages, you learn more approaches to solving problems. This enables you to choose the best approach for solving a problem from a larger repertoire of options.
What Really Matters
Even though learning more programming languages does give you more ways to approach problems, ultimately the choice of approach for solving a particular problem doesn’t matter much. What is vastly more important than the number of approaches to problems you know is the space of problems you know how to solve. A good programmer isn’t valuable because they can solve the same set of problems every other programmer can solve, just in different ways. A good programmer is valuable because they can solve problems that other programmers cannot.
Most programming languages and styles are designed with a similar purpose in mind: making it easy to express algorithms and procedures in a way a computer can execute them. While some programming styles are better than others at expressing certain procedures, they only make writing solving the particular problem at hand slightly easier. For the most part, any problem that can be solved using an object oriented style can also be solved in a functional style and vice versa. Knowing just one programming language and one programming style enables you to solve the vast majority of problems solvable in any programming language or style. In the larger picture, the particular choice of programming language and approach is mostly an implementation detail.
If you really want to become a better programmer and broaden the space of problems you can solve, instead of focusing on programming languages, you should focus on the parts of programming that actually enable you to solve more problems. Here are a few examples of areas outside of programming languages that having knowledge of broadens the space of problems you can solve:
- Operating Systems
- Web Development
- Distributed Systems
As an example, you should definitely learn how to setup and use a database. Nearly every non-trivial program uses some kind of database to keep track of application data. Why? Because databases are able to solve problems around handing data are extremely difficult to do with pretty much any programming language. For a few examples many databases:
- Can work with more data than you can work with in your typical programming language.
- Guarantee data won’t be lost, even if the power goes out.
- Make it impossible for your data to get into an inconsistent state.1
If you are familiar with how to work with a database, you can solve all of these problems with little to no effort by just setting up a database. No matter what programming language or programming paradigm you are using, you would much rather have the database handle these problems for you. Ultimately, learning how to use a database enables you to solve way more problems than learning another programming language does.
This applies just as much to the other areas listed. Each one of them enables you to solve more problems than you would be able to otherwise. How are you supposed to build a website without knowing about web development? How are you supposed to write an application that can handle a machine crashing without knowledge of distributed systems? For each of these areas you learn, you become able to solve problems you wouldn’t be able to before.
This is completely unlike learning more programming languages or paradigms, which for the most part are interchangeable. There just isn’t enough distinction between most programming languages and styles that learning a new language enables you to solve that many more problems then you could have before. At this point which do you want to learn: how to solve a problem in more ways or how to solve more problems?
- ACID compliant databases guarantee that if you execute code in a transaction either the entire transaction executes or none of it. This is called atomicity, which is the “A” in ACID. For example, if you are transferring money from one bank account to another in a single transaction in an ACID compliant database, the database will guarantee either the money will be completely moved or not at all. The database makes it impossible for the data to enter a state where the money was withdrawn from the source account but not deposited into the destination account. This is guaranteed even if the power goes out while the transfer is executing in the database!