Spectrum of Languages by Hardware Distance

Programming languages (and the ecosystems that surround them) are incredibly interesting. They can be sliced in many different ways based on syntactic similarity, type system similarity, suitedness for various problem domains, and many other attributes.

Below I present an spectrum of various languages, arranged by distance from the underlying hardware1:

A few interesting patterns become evident in this diagram:

  • Expressiveness Distance from Hardware
    • Usually the closer you are to the hardware, the more you have to think like a computer and less like a human, decreasing expressiveness.
    • There are some outlier languages (such as Go, Lua, and Forth) which are more expressive than their distance from the hardware would suggest.

  • Type systems tend to be similar for languages with similar hardware-distance.
    • Bare Metal languages like machine code and assembly have no type system at all. Every piece of data is just a machine word and no type checking is done at all.
    • Almost Bare Metal languages like C and C++ have a type system that is just strong enough to tell the compiler how to compile operations efficiently, but these type systems are not specifically designed for the elimination of bugs or expressiveness.
    • High Level languages care more about expressiveness, and they tend to divide into two camps: statically-typed (Java, C#) and dynamically-typed (Python, Ruby, Lisps).
    • Anything that is Intermediate Typed or below has a stronger focus on the type system, usually for preventing bugs or just having very precise types.

  • “PhD required below this line”
    • I have observed generally two large groups of people that work with programming languages, the Practitioners and the Academics. Each group uses their own specialized jargon2 and tends not to talk to each other that much.
    • Languages inside the “PhD required below this line” area are generally used primarily by Academics, and therefore their documentation (often only in the form of research papers) is difficult to read by Practitioners.
    • I currently group myself as a Practitioner who is trying to read Academic.
    • Of course some so-called Academic languages are sometimes used in practice for commercial systems. The Java bytecode verifier, for example, is defined in Prolog.
    • Many languages in or near this region are lumped under the vague term functional programming, which roughly translates to a programming style that avoids mutable data structures & side effects by default, or just “a language that feels like Haskell” (the canonical “functional” language).

  • Middle of the spectrum = Sweet spot
    • There are a quite a lot of languages in the middle layers (High Level and Intermediate Typed). Probably because they intersect most with expressive languages, which are the most fun to program in.
    • Programming near the hardware is unfun and generally unnecessary unless you’re writing an OS, an embedded system, a CPU-intensive scientific computation, or a graphics shader.
    • I suspect there aren’t as many languages at the bottom in Academic-land because there are fewer Academics than Practitioners, such languages are harder to write (because of more complex type systems), or because I simply am not aware of many such languages as a non-Academic.

  • Declarative Languages that are general-purpose are rare.
    • Most Declarative Languages are domain-specific. Arguably Prolog is general since it answers arbitrary questions from logic. And arguably SQL is general because most data stores (and every SQL database) is queryable with it.
    • Other examples of declarative languages not listed here are VHDL and Verilog (used for hardware design), and ReceiptTally3 (used for personal finance).

Related Articles

Series

This article is part of the Programming for Perfectionists series.


  1. When speaking of “hardware distance”, the hardware I am referring to is the common commodity hardware architectures such as x86 and ARM. It should be noted that there are also specialized architectures where Forth, Lisp, and Prolog are the assembly language. And some architectures like the Burroughs actually have typed memory and pointers, which eliminates a lot of the dangers of working with untyped assembly.

  2. Examples of Practitioner-jargon: “inheritance”, “generics”, “dependency injection”, “covariance”. Examples of Academic-jargon: “monad”, “functor”, “reduce”, “dependent type”, “currying”. More examples from this presentation on functional programming.

  3. ReceiptTally is a custom language of my own designed to describe household receipts. With this description it can be calculated who owes whom money for reimbursement purposes. I haven’t bothered to make this project public at this time.