Skip to content
Beskid The Beskid Book

Beskid

Jump to a Beskid service

Beskid

Jump to a Beskid service

1.5 Are we really standing on the shoulders of giants?

From assembly to VMs—how abstraction stacked up and which traps language designers keep stepping in.

Are we really standing on the shoulders of giants?

We tell ourselves each generation stands on the shoulders of giants. In practice we often stand on a pile of runtimes and call it progress.

Climbing a stack of runtimes

A compressed history of “getting further from the machine”

Section titled “A compressed history of “getting further from the machine””
flowchart TB
  assembly["Assembly — you are the machine (sort of)"]
  macros["Macros — copy-paste with consequences"]
  c["C — portable enough, segfaults included"]
  cpp["C++ — C with extra steps and a standards committee"]
  vms["Managed VMs — write once, run anywhere (terms and conditions apply)"]
  jit["JIT — optimize what you actually ran, eventually"]
  highlevel["High-level — express intent, pray the runtime agrees"]
  frameworks["Frameworks — express intent in the framework's dialect"]
  lowcode["Low-code — express intent with buggy, react-flow bootstrapped nodes"]

  assembly --> macros --> c --> cpp --> vms --> jit --> highlevel --> frameworks --> lowcode

Each step traded control for reach:

  • Assembly gave truth and pain.
  • C gave portability and manual memory.
  • Java / .NET pushed toward virtual machines so hardware details could be ignored—until they could not (GC pauses, container memory, AOT revivals).
  • JIT promised peak performance without ahead-of-time commitment; you paid in warmup, complexity, and “works on my machine” bytecode.

The run anywhere dream was real enough to reshape hiring. It also abstracted languages into runtimes until the runtime became the real product (CLR, JVM), and the language became syntax for feeding it.

Traps of the human mind when designing languages and frameworks

Section titled “Traps of the human mind when designing languages and frameworks”

“We survived C++ enterprise projects” becomes “C++ is fine for everything.” The failures are in postmortems, not conference stages.

“If Rust is hard, hard must mean good.” Sometimes hard means your tool is fighting your actual workload.

Shrug — false equivalence

Designers add escape hatches until the language is three languages in a trench coat. Compassion for power users becomes tax for everyone else.

“If you are not using X, you are doing it wrong.” X changes every eighteen months. Moral certainty does not.

When the VM is the platform, language innovation becomes workarounds:

  • Generics via erasure or boxing
  • Value types as a decade-long project
  • Async as state machine rewrite theater

Mind blown — VM workarounds

Beskid pushes assembly output without IL handcuffs and compile-time power because we are tired of negotiating with a runtime that updates slower than the language.

Each layer promises you can forget below. Then production reminds you: GC, thread pools, HTTP/2, and disk still exist. You just debug them with worse symbols.

This is fine — production fog

Shoulders of giants implies visibility. Abstraction towers imply fog.

Beskid is not anti-abstraction. It is anti-unpaid abstraction: layers you did not choose, cannot see in the binary, and cannot remove when the business rule is simple but the stack is not.

Next: 1.6 segfault or not to segfault.