Languages That Stretch Your DI Capabilities and Imagination
2026-07-11
DI means Design Intent — what people usually call “software architecture,” the expression of intent rather than just code. I’ve come to believe you don’t become a good architect by getting really good at one paradigm. You become a good architect by studying many paradigms, deliberately, including the ones that feel foreign or obsolete.
Most of us today learn one paradigm deeply — the function-based / functional paradigm — and mistake fluency in it for architectural skill. But DI is bigger than functions and call stacks. Below is a list of books, papers, systems, and talks that pushed my own thinking outside that box. None of them are “productivity hacks.” They’re worldviews.
Smalltalk
Start with the Smalltalk Blue Book — specifically Section Four, which quietly disappeared from the more commonly circulated Purple Book. Smalltalk isn’t “objects with methods” the way most OOP languages borrowed the idea. It’s a complete environment where everything, including the language itself, is a live, inspectable object. Section Four is where that worldview is most exposed: it gives an implementation of Smalltalk in a subset of Smalltalk, including code for the virtual machine and the then-new generational garbage collector.
Parsing as a paradigm
Parsing Expression Grammars — Bryan Ford’s original concept and paper — reframe parsing as ordered choice rather than ambiguous grammar resolution. It’s a genuinely different way to think about structuring recognition and control flow. OhmJS is a modern, very approachable implementation of these ideas, and worth playing with directly rather than just reading about.
BNF, and its more common successor properly called eBNF, is itself a DSL for writing parsers. PEG and OhmJS use a syntax very much like eBNF’s. But the purpose differs from what came before: traditional compiler-compiler tools like YACC are meant for specifying languages, whereas OhmJS is better understood as a DSL for specifying parsers.
Before PEG, I used recursive descent, and S/SL. PEG just makes this so much easier — almost like discovering regexes after years of hand-rolled string matching. PEG’s greatest contribution is arguably the return of backtracking, which had been mostly banished during the 20th century out of a bias toward premature optimization. Backtracking makes it much easier to describe parsers, even where it costs you some raw performance.
One of the first things I wrote in OhmJS (which I think of as an improved PEG) was a DSL I call RWR. Using OhmJS plus RWR, I built a small tool called T2T, part of a larger toolkit called PBP. With T2T — and the Ohm-editor grammar REPL — I can crank out custom little languages in minutes or hours. At this point I transmogrify these little languages into running Python code, often as PBP components or as stand-alone Python. I’ve also generated JavaScript, Common Lisp, and Odin code from the same little-language definitions.
Statecharts
David Harel’s statecharts extend finite state machines with hierarchy, concurrency, and broadcast communication — and they express behavior as a first-class architectural artifact instead of burying it in conditionals. I made a video of my reading of the original paper: Statecharts — Papers We Love video.
Logic programming
The bare essence of Prolog is that you can write exhaustive search using very little code. In our current bevy of programming languages, you need to write tangled code that contains loops within loops and encourages bugs and incomplete search strategies. Prolog and its descendants invert the usual relationship between data and control: you state relations, and the engine searches for solutions. See my Prolog-related referencesroundup, and miniKanren for a minimal, embeddable take on the same idea — relational programming small enough to implement in an afternoon and deep enough to reshape how you think about search and backtracking.
Atari Pong (1972)
This one is the sharpest possible contrast to “software architecture” as we usually mean it. The original 1972 Pong hardware fits on one page, is built from asynchronous components, and has no code at all. It’s pure architecture — signal flow and timing — with none of the sequential, function-call baggage we now treat as unavoidable. If you want a jolt to your assumptions about what “a program” even is, look at this schematic.
Sketchpad
Ivan Sutherland’s Sketchpad (1963) predates almost everything we now consider modern in interactive and object-oriented computing — constraints, prototypes, real-time graphical manipulation. It’s worth understanding as the ancestor a lot of paradigms forgot they had. Sketchpad was written in assembler — Sutherland did not need automated type checking and all of the baubles we’ve since added to create useful software.
The Big OOPs
Casey Muratori’s talk The Big OOPs argues that mainstream language design — OOP in particular — took a wrong turn for a huge class of real-world problems, game programming among them. Whether or not you agree with his conclusions, it’s a useful antagonist to sit with: it forces you to defend or abandon assumptions you probably never examined.
Unix V1 and the C that almost wasn’t
Research Unix is usually remembered as “written in C,” but V1 was assembler, and only V4 was ported to K&R C. K&R C and ANSI C are not the same language in spirit: K&R C is unapologetically tied to the utility of a specific machine (the PDP-7), while ANSI C is built around portability and type-checking across many architectures. Reading Unix history with that distinction in mind changes how you read the code — it’s a different set of design pressures than the C we write today.
Small-C
Small-C, also published in Dr. Dobb’s Journal, is where I learned what a compiler actually does — by implementing it on a V7 Unix system running on a PDP-11. Everything compilers have added since then is, in a real sense, just improvements on this basic idea. The Dragon Book is largely a way to make this same idea more efficient.
Holt’s Concurrent Euclid, the UNIX System, and TUNIS
Richard Holt’s book, Concurrent Euclid, The UNIX System, and TUNIS, especially Chapter 10, “Implementing a Kernel,” is a masterclass in expressing concurrent system design with a language built specifically for it, rather than bolting concurrency onto a sequential language after the fact.
S/SL
S/SL (Syntax/Semantic Language) is dataless — control flow only. It’s arguably the epitome of OOP and modularity, stripped of everything except the control structure that OOP is supposedly about. Seeing that idea in its purest form is clarifying in a way that “real” OOP languages, cluttered with data and syntax, rarely are. The code repository contains the S/SL specification, a version of S/SL written for C, and a full-blown compiler (PT Pascal) written in a Pascal version of S/SL.
Cordy’s Orthogonal Code Generator
James Cordy’s Ph.D. thesis work on orthogonal code generation — published with Richard Holt as Code Generation Using an Orthogonal Model (Software—Practice and Experience, 1990) — is worth reading right alongside S/SL, since it comes out of the same Toronto compiler lineage. In it, Cordy touches on techniques that look strikingly modern today: ideas that rhyme with Justine Tunney’s work on Binary Lambda Calculus, with Holt’s own Data Descriptors paper, and with a small DSL Cordy built for generating portable code using decision trees, which he called MISTs. Data descriptors in particular show how normalization — treating machine-level addressing as data to be normalized rather than handled as ad hoc special cases — can make code generation dramatically simpler to write.
Tiny BASIC
Tiny BASIC is a minimal BASIC interpreter designed to fit in a few kilobytes of memory on early microcomputers. The canonical source is in Volume 1 of Dr. Dobb’s Journal — short enough to read whole, in one sitting, rather than in disconnected fragments.
Frits van der Wateren’s Lisp
Frits van der Wateren’s Lisp is another small, complete implementation worth reading end-to-end — the kind of codebase small enough to hold entirely in your head at once, which is exactly the point of studying it.
SectorLisp
SectorLisp is a Lisp interpreter that fits in a 512-byte boot sector. It’s tiny — purer than pure functional programming, in the sense that there’s no room left for anything but the essence of the idea. A good antidote to the notion that expressive power requires size.
Prolog Control in 6 Slides
Nils Holm’s Prolog Control in 6 Slides distills the control mechanism of Prolog — unification, backtracking, the resolution loop — into something you can hold in your head in one sitting. Short, dense, and worth re-reading more than once.
Forth
Thinking Forth by Leo Brodie isn’t really about the Forth language — it’s about a design philosophy: factoring problems into small, composable words, thinking bottom-up, and treating the language itself as something you extend to fit the problem rather than the other way around.
Rebol and Altscript
Rebol, designed by Carl Sassenrath — also the architect of the Amiga OS kernel — is one of the first languages to have PEG-style parsing built directly into the language itself. The result is that Sassenrath was able to build very powerful libraries using a surprisingly small amount of code. (See also the official Rebol site.)
Sassenrath’s successor project, Altscript, proposes a very interesting and very rich set of fundamental data types — around fifty lexically recognized “atoms” built directly into the language.
Video presentations
Two talks that belong in this list even though they’re not papers or code:
Alan Kay, The Computer Revolution Hasn’t Happened Yet — a reminder that most of what we call “modern” computing is still a fairly narrow, accidental slice of what was actually envisioned.
Capt. Grace Hopper on Future Possibilities — my own writeup of her talk, which is startlingly prescient about where computing was headed.
Why this matters for DI
None of these are “better” than the functional paradigm. That’s not the point. Each one makes a different set of tradeoffs visible — between data and control, between synchronous and asynchronous, between portability and machine-specific utility, between huge and minimal. If you’ve only ever thought in one paradigm, you don’t know which of your assumptions are fundamental and which are just habits picked up from the tools you happened to learn first.
Studying paradigms outside your comfort zone is how you build the vocabulary to express Design Intent clearly — not just to write code that runs, but to build systems whose architecture says what it means.
See Also
Email: ptcomputingsimplicity@gmail.com
Substack: paultarvydas.s. bstack.com
Videos: https://www. youtube.com/@programmingsimplicity2980
Discord: https://discord.gg/65YZUh6J. q
Leanpub: https:. /leanpub.com/u/paul-tarvydas
Twitter: @paul_tarvydas
Bluesky: @paultarvydas.bsky.social
Mastodon: @paultarvydas
(earlier) Blog: guitarvydas.github.io
References: https://guitarvydas.github.io/2024/01/06/References.html
Paid subscriptions are a voluntary way to support this work.

