Over the past week or two I have pursued peeling back the programming language onion. What a bloomin onion it is 😋. Most recently I took on the subject of programming languages being compiled vs interpreted. Interesting as this subject is, compiled vs interpreted becomes almost insignificant when looking at languages from a hierarchical perspective. So what makes a language high-level vs low-level? Perspective for one. To Python, C is a low level language, however to C, Assembly Language(asm) is a low level language.
When someone refers to a language being low level they are referencing the language’s level of abstraction from Machine Language, also known as Binary. While Binary deserves it own blog post the quick synopsis of the language is that it consists entirely of 0’s and 1’s. Those 0’s and 1’s are the only way programmers can directly communicate with the physical hardware that make up a computer. These 0’s and 1’s are actual conversions for electrical voltages that are sent through your computer’s motherboard and central processing unit(CPU). Machine Language has essentially only two boolean states of false 0(0 Volts / Ground) or true 1(+5 Volts). This is the juncture between software engineering and electrical engineering. I am NOO electrical engineer but if you want to read more about Binary you can here.
So the the two takeaways from this should be that Machine Language / Binary is the lowest level language and it is the only language that computer hardware can understand. One step up from Binary is Assembly Language(asm). Programs written in asm are directly executable on the computing hardware and without the need for a compiler or interpreter. Low level languages having such a direct relationship with the computer hardware are very efficient, lightweight, and have complete control over things like memory allocation. These reasons are why you most often see Assembly being used for kernel architecture, firmware, and operating system architecture. Asm is difficult to use and quite complicated which is why you rarely see it being used outside of the above very specific parameters. As an example here is hello world in asm.
So your computers operating system manages computer hardware and software resources as well as provides common services for computer programs (think keystrokes from your keyboard). The kernel is the core program of a computers operating system. It is the first program loaded on start up and does three main things.
- Handles the rest of the start up process
- Handles the input output requests from other programs
- Manages memory and other hardware peripherals (keyboard, monitors, printers, speakers)
The most popular kernel known today is Linux. The Linux kernel is also at the heart of all Android devices.
Hopefully now the name low level language makes sense. The lower you go the more foundational the processes the language is responsible for. Moving one step up from Assembly we reach C. C is the tie that binds low level and high level languages. Most of Mac OS, Windows, and Linux are written in C, C++ and some assembly.
C sits in the middle due to its level of abstraction from machine language. The further the abstraction from machine language the closer to human language we get. So something like Ruby which reads almost like english is very high level and abstracted as far away from machine language as possible.
While it is much easier to develop functions and objects to build a program in Ruby versus asm, Ruby as a language has no control over things like memory allocation. So to conclude this short little catch up on languages from a hierarchical perspective, we have learned that the lowest level languages are closest to the machine. Not only in deployment but also in responsibility. The lower you go the closer you are to physical hardware and eventually leave the software engineering world and enter the electrical engineering world. Happy digging!