💾 Archived View for yujiri.xyz › software › guide › programming.gmi captured on 2023-01-29 at 04:45:54. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
Learn programming for good instead of profit
First, let's start with the concept of an executable file.
Executable files are files that can be run ('executed') directly by the operating system (OS). On Windows they end in `.exe`; on Linux or Unix they have no name extension. These files contain the actual list of instructions for your processor to execute - in the form the processor needs them in, not a text form that represents those instructions to humans. So, if you open an executable file in a text editor, it'll look like gibberish, not like code.
(Executables files are also called 'binaries'.)
An assembly language is a textual way of representing those same instructions so that humans can write and read them. A program called an assembler is used to convert the text (called "source code") into an executable. Assembly language is still incredibly hard to work with though, even for a very experienced programmer, so that's why "higher-level" languages exist.
https://en.wikipedia.org/wiki/Assembly_language
The languages most people actually use, like C or Python, are called "high-level" languages. Unlike assembly code, source code in a high-level language is not a direct description of machine instructions. Each machine instruction does something primitive like "move the number from memory address 0xFF68A0C0 to memory address 0xFF68A0B0", whereas a line of code in a high-level language does something like "add this item to a list". The latter is made of the former, but you don't have to deal with all the inscrutable details.
Like assembly languages, high-level languages require a program to convert the source code into machine instructions, but it's not called an assembler, it's called a compiler. Compilers are much more complex than assemblers because source code in a high-level language isn't just a textual representation of machine instructions, so translating it to machine instructions is a very complex process. (Often they do it by first translating the high-level code into assembly code and then running an assembler on that.)
High-level languages make software as we know it possible, because they're much easier and more efficient for humans to read and write. If a program written in C is 30 lines long, the equivalent assembly code might be 100 lines. And the equivalent Python code might be only 10 lines! Some high-level languages are higher-level than others - in fact, we often think of C as a low-level language, because it's low-level compared to other high-level languages.
In general though, high-level languges come with the tradeoff of worse performance, because the generated machine instructions won't be as good as they could be if they were hand-optimized by a human. It's like how translating human speech between languages often loses some precision or nuance. Those 10 lines of Python will probably run much slower than the 30 lines of C. And the 30 lines of C will probably run slower than the 100 lines of assembly (but only slightly).
Actually, not all high-level languages use a compiler. Some of them use an interpreter instead.
The difference is that whereas a compiler converts your source code to an executable so the operating system can run it, an interpreter reads and runs your code by itself. It doesn't convert it to an executable. The interpreter itself is an executable program written in a compiled language (usually C). Python is actually an interpreted language (and that's why the 10 lines of Python would run "much" slower than C).
Interpreters are more convenient than compilers in some ways, but they have two downsides: