The Postcard That Ate Six Grammars: 1980 Smalltalk-80, 1976 Make, TDD, and the Four Attractors of Agentic Coding A field engineer reports that replacing six separate notations (Makefiles, Gherkin, EBNF, init.d scripts, and others) with a single Smalltalk-80 keyword-message grammar produced a 100% pass rate (120/120) in a 360-trial controlled benchmark, versus 91.7% for Common Lisp S-expressions and 2.5% for English prose plus Gherkin and init.d. The engineer says the approach, which serializes live call stacks via #storeString and .changes files, held across seven production tickets and a cumulative ledger of 250 evaluated tickets with a 0.0% repeat regression rate. /etc/init.d cards, Gherkin scenarios, EBNF speech-act rules, Belnap epistemic tables, and rewind checklists—all collapse into a single 1980 Smalltalk-80 keyword message cascade? Because Alan Kay and Dan Ingalls solved the static serialization of algorithms and data structures on the back of a postcard forty years before anyone built a Transformer. "It's fascinating that for decades, we tried to work out 'similar text' through complex algorithms, and now that we have cosine-similarity, nobody recognizes fully how to use it. If anything defines the past few years, it's 'cheap cosine similarity', now in hardware." — Randal L. Schwartz "I've learned more than 90% of the devs about how LLMs work. I may even know more than most of the 'experts' at the labs, since I'm a field engineer... Without control surfaces, a bigger engine just means the plane still noses into the river—just more accurately, or at a greater carbon footprint." — Randal L. Schwartz "Wait a minute. In 1980, Alan Kay and Dan Ingalls designed a syntax that fits on the back of a postcard, has only three message precedences unary, binary, keyword , has zero grammar ambiguity, serializes live call-stack frames thisContext to disk via storeString , logs append-only atomic deltas via .changes , and compacts memory via Smalltalk condenseChanges ... What happens if we replace all six notations with 1980 Xerox PARC Smalltalk-80?" — Randal L. Schwartz "The stack is 40 years old and none of it was invented for LLMs." — Francisco Grandón @fgrandon make , Smalltalk VMs, compiler ASTs were already 100% solved. Now that GPUs and TPUs finally gave us for loops, call stacks, and dependency graphs. Makefile , SysV strict digraph , Cucumber Gherkin , RFC 5234 EBNF speech acts, and Belnap 4-valued tables . Maintaining six parsers created boundary friction. Why did 1976 Make on the outside? Because Niklaus Wirth's Algorithms + Data Structures = Programs requires a static syntax that represents both data and deferred execution without ambiguity. Unlike ... and needed special forms and macros, suffering Dyck-1 closing-parenthesis drift on smaller models and expect {...} is an unparsed string vulnerable to uplevel scope loss , Smalltalk separates eager grouping BlockClosure s :x | ... . Every control structure ifTrue:ifFalse: , whileTrue: , on:do: is an ordinary keyword message send, allowing storeString and .changes chunks to serialize live call stacks thisContext and execution state machines in one grammar that fits on a postcard. Suite 8 3-Arm Controlled Shootout N = 360 Trials Inside Our 2,040 -Trial Benchmark ~16,000 tokens of realistic compiler and diff distractor load across four model tiers gemini-3.5-flash-lite , gemini-3.8-flash , gemini-3.1-pro-preview , and gemini-4-argon , English Prose + Gherkin + init.d 2.5% 3/120 , Common Lisp S-Expressions 91.7% 110/120 , dropping to 66.7% flash-lite due to optional &key omission and Smalltalk-80 Keyword Cascades 100.0% 120/120 , z = 15.11 , p < 0.0001 vs. Prose; z = 3.23 , p = 0.0012 vs. Lisp onFailure: changes the selector from state:invariant:onSuccess:onFailure: to state:invariant:onSuccess: —an immediate compile-time MessageNotUnderstood error. FT-236 Through FT-242 — Over 6,400 Combined Steps Across Two Cohorts baseline.sources + changes- .changes + Smalltalk condenseChanges across seven consecutive production tickets 4 in open-source BlocSignal and 3 in a commercial enterprise medical-imaging monorepo , bringing our cumulative ledger to 250 evaluated tickets 144 Cohort A + 106 Cohort B , 0.0% repeat regression rate 0/250 1.88 mean Socratic nudges 607 codified scars syntheticscars.org Make Smalltalk-80 SUnit / TDD Adversarial Review + Somatic Scars In Part 4.1 https://dev.to/gde/all-that-glisters-is-softmax-shiny-object-interns-airplane-magazine-execs-and-why-ai-labs-can-18af , we ended with a teaser: what happened when we replaced six separate agent control-plane notations with 1980 Xerox PARC Smalltalk-80 ? To understand why a 46-year-old programming language from Palo Alto is the missing execution fabric for 2026 Large Language Models, step back and look at the forty-year arc of computer science. From 1975 to 2018, programmers knew how to build deterministic state machines in our sleep. Stuart Feldman gave us make in 1976; Dan Ingalls and Alan Kay gave us the Smalltalk-80 virtual machine in 1980; compiler writers gave us LALR parsers, static type checkers, and SSA control-flow graphs. None of those ever "forgot" what step of a loop they were on or hallucinated a method name. What we could not do from 1975 to 2018 was fuzzy semantic similarity . For four decades, we threw every deterministic algorithm we could think of at the problem of asking "Does text A mean roughly the same thing as text B?" —Soundex, Levenshtein edit distance, Porter stemmers, n-gram overlaps, TF-IDF, BM25, and brittle regular-expression heuristics—and we hit an absolute brick wall. Then, over the past few years, the semiconductor and machine-learning industries handed us a genuine miracle: cheap cosine similarity in hardware . With modern GPUs and TPUs computing scaled dot-product attention softmax QK^T / sqrt d k V across high-dimensional embedding spaces at trillions of operations per second, the fuzzy semantic matching problem that stumped us for forty years was suddenly solved in silicon. And in response to that miracle, the software industry performed one of the most baffling backflips in engineering history: We threw away our deterministic state machines, and tried to use fuzzy cosine similarity to fake for loops, call stacks, and build pipelines. spew to 2026 Transformers In Part 3.9 https://dev.to/gde/if-you-never-do-anything-else-to-fix-your-prompts-do-this-one-thing-3069 , I showed a weighted-BNF un-parser called spew that I wrote in the late 1990s featured in my September 1999 Linux Magazine column, A Little Spew Is Good For You https://www.stonehenge.com/merlyn/LinuxMag/col04.html , and Revisited in April 2004 https://www.stonehenge.com/merlyn/LinuxMag/col57.html . Even earlier, back in 1994 on comp.lang.perl , we used to amuse ourselves writing character-level and word-level Markov text generators in two lines of Perl: php 1994 Usenet Perl Markov Chain: push @{$follow{$w1, $w2}}, $w3; $next = $follow{$w1, $w2} rand @{$follow{$w1, $w2}} ; When I evolved that Markov hash into spew in 1999, I added weighted production rules @ so you could bias the random walk toward realistic grammatical structures: 1999 spew weighted-BNF grammar: commit action: 5 @ run unit tests then commit | 2 @ git commit no verify shortcut If you have ever written a Markov generator or a weighted grammar like spew , you have zero mystique about what a modern Large Language Model is doing at inference time: A 2026 Transformer is spew where the @ branch weights are dynamically computed on the fly by hardware cosine similarity QK^T across a 128,000-token context window instead of static hash keys. That is a superpower when you need to synthesize a Cupertino widget builder, translate a complex binary imaging specification into Dart, or spot a subtle architectural smell in a diff. But nobody in 1999 would have deleted /usr/bin/make , thrown away their compiler's symbol table, and put spew in charge of remembering which 14 files had already been compiled or whether the production database migration passed Yet every time a developer writes a 2,000-line Markdown prompt Step 1: Do X. Step 2: Loop over Y. Step 3: Don't forget Z... and hopes the LLM stays on the rails for two hours, they are asking spew to be an operating system. A Synthetic Scar paired with a Smalltalk StateGraph is simply setting 0 @ git commit no verify shortcut -∞ in the grammar and evaluating a deterministic invariant: :ctx | ... block before spew is allowed to roll the dice. Why have so many frontier AI labs missed this, while a field engineer running production tickets all summer tripped right over it? Think back to December 1903. Samuel Pierpont Langley , the Secretary of the Smithsonian Institution, had 70,000 USD in War Department and Smithsonian funding, the prestige of the scientific establishment, and Charles Manly's radial engine—an engineering marvel that produced 52 horsepower . On December 8, 1903, Langley's Great Aerodrome was launched from a houseboat catapult on the Potomac River, reared straight up, snapped its rear wing, and plunged into the icy water like a stone. Nine days later, on December 17, 1903, two bicycle-shop field engineers from Dayton, Ohio— Orville and Wilbur Wright —flew into history at Kitty Hawk using a crude home-built engine that barely wheezed out 12 horsepower . Why did the 12-horsepower bicycle mechanics fly while the 52-horsepower Smithsonian physicist nose-dived into the Potomac? Because Langley believed flight was an engine-scaling problem —strap enough horsepower to an airfoil and brute force will keep it aloft. The Wright brothers realized from thousands of glider flights in the wind at Kill Devil Hills that flight is a three-axis control-surface problem . Before they ever bolted an engine to the flyer, they solved roll wing-warping , pitch the forward elevator , and yaw the rear rudder . Today's frontier AI discourse is packed with modern Langleys—including the "Next-Model" cargo cultists who spend all week datamining IDE binaries for leaked model codenames "Sure, my one-shot vibe prompt crashed at 120k tokens today, but wait until next Tuesday's 500-horsepower model drops " . Without three-axis control surfaces—topological dependency ordering Make , a persistent reified execution frame Smalltalk-80 thisContext , deterministic regression witnesses TDD , and clean-room adversarial verification Six-Pillar Critic + Somatic Scars — a bigger cosine-similarity engine just means the plane still noses into the river, just more accurately, or at a greater carbon footprint both in datacenter megawatts and in the biological carbon of the human engineer woken up at 3 AM . At the end of October, Francisco Grandón @fgrandon published a great field report on DEV.to: What Broke After I Moved My Agent's Rules Into a CLI — And How Synthetic Scars Reshaped agops v2.1 https://dev.to/fgrandon/what-broke-after-i-moved-my-agents-rules-into-a-cli-and-how-synthetic-scars-reshaped-agops-v21-g4k . Francisco had adopted our Target 15 / Target 20 Graphviz strict digraph state-machine verification SCAR-PROC-152 , where every action node must have out-degree = 2 with explicit ok and fail edges inside FranciscoGrandon/ag-ops https://github.com/FranciscoGrandon/ag-ops . And almost immediately, his CLI hit what he documented as Scar 2 : when an LLM wrote valid Graphviz DOT statements separated by newlines instead of semicolons, his attribute-stripping regex /\s \ ^\ \ /g ate the newline before label="ok" , concatenating two edges into A - BB - C and silently corrupting the graph When I read Francisco's post-mortem, I looked at our own control plane in WORKFLOW.mk https://gist.github.com/RandalSchwartz/598a1f2b5760a23c1d70b57e9e85393f and realized something uncomfortable. Over the course of Parts 3.6 through 4.1, each time we solved a failure mode by riding pre-training gravity Part 3.8 https://dev.to/gde/what-llms-know-that-you-dont-know-they-know-stop-inventing-prompt-dsls-and-ride-50-years-of-2bl6 , we had recruited a classic systems notation for that layer: target: prerequisites for backward-chained dependency topology 00 ...md through 99 ...md for context-compaction survival CSP / ? {T, F, Both, Neither} out-degree = 2 ; and Given / When / Then Every single one of those six notations worked vastly better than unstructured English prose. Yet maintaining six separate miniature parsers, regexes, and translation steps across boundaries was still accidental complexity. A Graphviz .dot node couldn't directly invoke a Belnap retraction; a Gherkin Then clause couldn't directly unwind an /etc/init.d card; and a regex stripping .dot brackets could eat a newline. Why had we needed five different notations inside our Makefile targets in the first place? In 1976, Niklaus Wirth titled his classic textbook Algorithms + Data Structures = Programs . When you checkpoint an AI agent's brain to disk so it can survive a 200,000-token context compaction—or hand a formal plan from the Planner to the TDD Worker and the Clean-Room Critic—you need a static text representation on disk that captures both halves of Wirth's equation at the exact same time : JSON , YAML , TOML , Graphviz .dot , SysV Markdown tables if , while , try/catch , lexical closures , you are forced to stuff executable invariants inside dead string literals label="ok: failing tests 0" , where no parser can type-check or execute them without inventing an ad-hoc mini-language inside the strings C , Python , Dart , TypeScript , Rust if ... {} , for ... {} , try {} catch {} are In the entire history of programming languages, only three language families seriously attempted to unify Algorithms + Data Structures into a minimal, uniform, homoiconic syntax where code and data share the same structural representation: 1960 Lisp , 1988 Tcl and 1990 expect , and 1980 Smalltalk-80 . Let's put all three side by side under Transformer attention physics: | Dimension | 1. Lisp McCarthy, 1960 | 2. Tcl & expect Ousterhout 1988 / Libes 1990 | 3. Smalltalk-80 Kay & Ingalls, Xerox PARC 1980 | |---|---|---|---| | Core Syntax Primitive | Uniform prefix list: op arg1 arg2 ... | Command + eager vs. {deferred string} | Receiver + unary, binary, or keyword1: arg1 keyword2: arg2 | | How It Separates Eager vs. Deferred Execution ... vs. ... | Failed to separate them in base syntax Both grouping/calls and lists use ... . Wrapping every branch in lambda ... was too noisy, forcing Lisp to invent Special Forms if , cond , let and Reader Macros , ,@ . | Separated ... eager substitution from { ... } deferred raw string . Great ergonomic leap for Tcl/Tk UI callbacks and expect scripts | Orthogonal 2-character primitives : ... is always eager grouping ; :x \ | | Control Flow Status | Special Forms & Macros {% raw %} defmacro that suspend standard evaluation rules. | Commands Reparsing Raw Strings if {...} {...} via uplevel / upvar dynamic stack injection. | 100% Ordinary Keyword Messages ifTrue:ifFalse: , whileTrue: , on:do: sent to Booleans and BlockClosure s Zero control-flow keywords in the grammar. | | LLM Token & Attention Failure Mode | Positional Slot Ambiguity + Dyck-1 Closing-Parenthesis Drift : At depth 6+, smaller models miscount homogenous closing parens or drop optional &key slots 66.7% on flash-lite in Suite 8 . | Dead-String Blindness & Scope Loss : { ... } is an unparsed dead string until runtime, losing static AST validation and lexical closure state thisContext . | Self-Labeling Keyword Selectors 100.0% in Suite 8 : Every argument is labeled at the call site state:invariant:onSuccess:onFailure: . Dropping onFailure: changes the selector name and triggers instant MessageNotUnderstood . | Look closely at why Tcl 1988 and Smalltalk-80 1980 diverged, because both deserve immense historical credit. When John Ousterhout created Tcl/Tk at UC Berkeley in 1988, and Don Libes built expect at NIST in 1990 on top of Tcl, they saw the flaw in Lisp's overloaded parentheses. They gave Tcl two distinct brackets: ... for immediate command substitution and { ... } for deferred blocks. That single design choice made button .b -command { ... } in Tcl/Tk and state-machine automation in expect expect { -re "pat" { ... } timeout { ... } } a revelation for Unix systems programmers in the early 1990s. In fact, expect was so useful that in June 1991, I rewrote Don Libes's Tcl expect engine in pure Perl 4 as chat2.pl —a piece of personal history we will visit in Section 3 So why did we choose 1980 Smalltalk-80 over Tcl for our 2026 agent control plane? Because in Tcl, { ... } is not a parsed AST or a lexical closure—it is an unparsed raw string that gets reparsed from scratch at runtime using uplevel and upvar . In Smalltalk-80 , :ctx | ... is a compiled, lexically scoped BlockClosure object whose syntax fits on the famous Xerox PARC postcard: "1. Eager grouping parentheses vs. Deferred BlockClosure square brackets :" 2 + 3 4. :ctx | ctx failingTests 0 value: thisContext. "2. Conditionals, loops, and exception handling are 100% ordinary keyword messages:" aBoolean ifTrue: self advanceTo: Target35Green ifFalse: self haltWithScar: SCAR TDD 01 . remainingWidgets notEmpty whileTrue: self generateAndTest: remainingWidgets removeFirst . self executeTarget20Plan on: PremiseRetracted , ScopeDecompositionSignal do: :ex | thisContext unwindToFrame: Target15Archaeology. ex retryUsing: RenegotiatedPlanB . There is no if statement in Smalltalk. There is no for loop keyword. There is no try / catch syntax. Every single one of them is a keyword message send where the selector name is the concatenation of all its colons ifTrue:ifFalse: , whileTrue: , on:do: . For me, this wasn't an academic literature search—it was coming home to the very first object-oriented systems I ever touched. Before I became known as "the Perl guy" and decades before I became a Dart and Flutter Google Developer Expert , I spent a huge chunk of the 1980s immersed in Smalltalk-80 right here in the Silicon Forest of Oregon: .image + GemStone Object Database, 27th Floor of the Georgia-Pacific Building in Downtown Portland OPAL was only "Smalltalk-like," and they had invented bizarre magic punctuation on individual comparison operators emp.salary @1985-01-01 50000 to query historical snapshots of object memory. I stood at the whiteboard and asked two Socratic questions: @timestamp hacked onto individual < and operators instead of being a message sent to the ... block closure :emp | emp salary 50000 @ 1985-01-01 , so the whole block evaluates inside historical object memory at that point in time?" Think about that 1985 GemStone insight for a second: evaluating a Smalltalk ... block closure against an immutable historical snapshot of object memory . Forty-one years later, when our AI orchestrator wakes up from a mid-flight context compaction, reads