Building Software

Engineering Fundamentals for the Agent Era

Contents Section 3, The Machine

Languages, Compilers and Runtimes

Mistakes to catch in review

  1. A blocking call inside an async handler that stalls every other request on the event loop.

  2. A type-checker escape hatch (an any type, a forced cast, an ignore comment) that silences a real error instead of fixing it.

  3. An object mutated while other code still holds a reference to it, so a change in one place shows up somewhere unrelated.

  4. An unbounded in-memory cache or a closure holding large objects, leaking memory until the process is killed.

How source code becomes running behavior: parsing, compilation, interpretation, type systems, memory management and concurrency models.

Topics

Compilation, Interpretation and JIT
How languages turn source into machine instructions, bytecode or interpreted steps, and what that means for speed and for when errors appear.
Type Systems
Static and dynamic typing, what types can prove, and how to use them to catch mistakes before code runs.
Memory Management
Stack and heap, manual allocation, garbage collection and ownership, and the bugs each approach allows.
Concurrency Models
Threads, event loops, async/await and actors, and how each runtime decides what runs when.
Programming Paradigms
Imperative, functional and object-oriented styles as tools, and when each makes code easier to reason about.
Modules, Packages and Linking
How code finds other code through imports, module resolution, bundling, and static and dynamic linking.

You understand it when you can

  • Trace a function call through the call stack, including where each value lives and when it is freed.
  • Explain what a type checker can prove about a given function and what it cannot.
  • Predict the output order of a short program that mixes synchronous code, promises and timers.

Drill

An agent wrote an async upload handler that hashes each file with a synchronous, CPU-heavy function and stores results in a module-level map with no size limit. Find why response times spike for every user during uploads and why memory climbs until the process restarts.

Start here

Watch

Garbage Collection (Mark & Sweep) - Computerphile

Laurence Tratt, 2023. 16-minute explainer.

Explains manual allocation versus tracing garbage collection and reachability, which is why an object still referenced from a module-level map or closure is never freed.

"Simple Made Easy" - Rich Hickey (2011)

Rich Hickey, 2011. 62-minute talk.

Argues that shared mutable state tangles unrelated parts of a program, and makes the case for values and immutability that underlies the functional paradigm.

Read

Crafting Interpreters

Robert Nystrom, 2021. Free to read online.

Builds a tree-walking interpreter and then a bytecode VM with closures and a garbage collector, turning parsing, compilation and runtimes into something you have implemented.

Effective TypeScript: 83 Specific Ways to Improve Your TypeScript

Dan Vanderkam, 2024, 2nd edition.

Concrete items on what the type checker can and cannot prove, why any and type assertions hide real errors, and how to design types that rule out invalid states.

The Rust Programming Language

Steve Klabnik, Carol Nichols and Chris Krycho, 2026, 3rd edition. Free to read online.

Its ownership and borrowing chapters teach stack versus heap and when memory is freed more clearly than any GC-language text, and it includes a full chapter on async.

Primary sources