How does our code makes its way into something that does something on our computer/phone/smart device? Find out!
If we go all the way down into how our computers (or any digital device with a processor) operate, they react to instructions in binary made up of 0’s and 1’s. As human developers, most of us don’t write our code in terms of 0’s and 1’s, though. We write our code in a variety of programming languages with many made up of English-looking words and symbols. How do we go from the code we write to the very specific binary instructions our computers can understand? That’s where words like compiling and compilers (and a little bit of transpiling as well) come in, and this article will help explain what they all mean.
When we talk about programming languages, a really popular way of classifying them is in terms of how high-level or low-level they are. A high-level language is one that is easier for humans to read and write. The following is an example of code in a high-level language:
def cheeseshop(kind, *arguments, **keywords): print("-- Do you have any", kind, "?") print("-- I'm sorry, we're all out of", kind) for arg in arguments: print(arg) print("-" * 40) for kw in keywords: print(kw, ":", keywords[kw])
Notice that the code reads sorta like a story in a really poorly translated children's book. A low-level language is really designed with the computer as the audience, as we can clearly see in the following snippet:
0x 60 00 00 80 0x A4 00 00 00 0x 60 01 00 84 0x A4 01 01 00 0x 60 02 00 00 0x 60 03 00 04 0x 60 04 00 00 0x 60 05 00 01 0x 08 00 00 02 0x 20 00 00 03 0x 20 04 04 05 0x 11 20 04 01
To help you better make sense of all of this, the following diagram lists where some of our more popular programming languages fall in this high-level vs. low-level spectrum:
Now, this diagram isn’t by any means a comprehensive listing of all programming languages, but it does give an idea of the relative high-levelness and low-levelness of where some of our favorite languages stand. For the most part, especially if you are a regular reader of this site, you probably lean towards the high-level end of this spectrum. How does all of this reconcile when the code we write and what our computers care about are so different? The answer lies in something known as a compiler.
When we write our code in a high-level language, depending on the language used, a conversion takes place where the high-level code is converted into lower-level code. This conversion, formally known as compiling, is done by a program known as a compiler:
What a compiler does is straightforward. It takes our high-level code as input and outputs a lower-level equivalent. Each programming language that supports being compiled, comes with its own set of compilers that bring their own quirks and optimizations to the table. How low-level a particular compiler targets its code will vary as well. There may be cases where multiple compilation steps are needed to get to a state our computers can understand. There may be cases where just a single compilation step will do. Luckily, unless you really care about the details, all of this compiling and re-compiling happens behind the scenes. All we have to do is press the big compile/build button in our IDE of choice (or run a command via your Terminal/Command Prompt/etc.), and the app we are building will be ready to run.
There is a whole lot more depth and breadth to compiling and transpiling than what we looked at here, but the goal is to provide you with an overview of what these terms mean when you encounter them in the wild. If you go your entire life and just use the word compile to reference how our high-level code ultimately manages to do something on a device with a CPU, you would be fully in the clear. Even in cases where transpiling happens, that is a detail that most documentation and project overviews simplify by using the compile/compiler terminology instead. While technically this simplification may be inaccurate, for most cases, this distinction doesn't really matter. In all of our programs, our code gets turned into another form of code. Whether that is through compilation or transpilation is something we can debate over coffee and not bore the rest of the world with!