Programming Language Layer Cake
There are many different programing languages in existence today (I’m going to write about the languages I am familiar with) and I like to visualise their relationships as layers of a cake. There are two main ways to categorise programming languages: as having high or low levels of abstraction and as either compiled or interpreted languages.
The bottom half of the cake consists of the languages with low levels of abstraction, with microcode at the bottom and C++ at the top, all of these languages are compiled languages which means their source code is interpreted and compiled into a lower level language e.g, C++ is compiled into assembler. I categorise C++as a lower level language for the purposes of this diagram as its memory management is still a manual process unlike the languages in the layers above it, which makes it less trivial to use.
Microcode is the lowest level of abstraction available and it is the programming language used to create assembly language instructions. Assembly Language is the language used by computer processors (CPUs) and is specific to each CPU family and is also the lowest level at which software can typically interact with the CPU. Next is the common low level languages C and C++ which I’ve bundled into the same layer as C++ can compile C code so they are not really completely distinct. Although C++ is a higher level language than C as it supports object oriented programming which is typically considered a feature of high level languages.
The top half of the cake can be roughly split in to two groups of programming languages: those languages that are compiled (blue box) into a lower level language before execution by a compiler and those that are interpreted (green box) at run time by an specific interpreter program. The bottom half of the green and blue boxes represent the respective compilers and interpreters for the languages. It is worth noting that although the .net programming languages (C#, CLR C++ and VB.net) and the Java family of languages are all compiled, they are compiled into byte code executables before they can be executed (run) by a virtual machine (usually written in C/C++). The interpreted languages Ruby, php and Python are not compiled before execution but are interpreted at run time by an interpreter program (again usually written in C/C++). Interestingly interpreters do exist to process Ruby (JRuby & IronRuby) and Python (JPython & IronPython) source code into byte code for the Java virtual machine or .net CLI, allowing ruby or python to be run on any Java or .net CLI virtual machine.
Compiled languages like Java or .net must be recompiled before they can run on a different virtual machine however this is usually not a serious issue as .net and Java virtual machines exist for most opereating systems in some form or another. Recompilation is not a requirement for interperated lanagues which only require a functioning intererator on the target operating system to be able to be run, which makes them easier to use across multiple operating systems and leds to them being considered more portable than the compiled languages.