Simplification and Two Kinds of Code

surprisetalk1 pts0 comments

Simplification and Two Kinds of Code - by Paul Tarvydas

Programming Simplicity

SubscribeSign in

Simplification and Two Kinds of Code<br>2026-07-16

Paul Tarvydas<br>Jul 16, 2026

Share

Simplification has its benefits. Sometimes it’s the whole point.<br>I built a little DSL — a Solution Centric Notation, or SCN, my name for a small language aimed at one specific problem rather than general-purpose programming. I called this one “RWR,” and I leaned on three simplifications to make it:<br>Make it easy to transpile to an existing language, like JavaScript, instead of writing a real compiler.

Use only strings as the data model — no arrays, no objects, no user-defined structures.

Lean on eval() during development, which gives you most of the benefit of a compiler with a fraction of the ceremony.

RWR solves one narrow problem. OhmJS, the parser generator I was using, expects you to write its “semantics” actions — the code that runs when a grammar rule matches — in JavaScript. We usually can’t see the forest for the trees. Rewriting text is a simple problem, but we’re tempted to reach for all the overkill a general-purpose language makes available anyway, just because it’s sitting right there.<br>The point here is that we’ve overcomplicated our own problems by trying to generalize, by trying to produce general-purpose languages. By thinking about only what’s needed to successfully generate SCNs, I discovered I only needed strings and a handful of simple string operations. Those operations are a subset of what’s available in most modern programming languages, so it was like cherry picking — choose the minimal subset of what would actually be useful, and ignore the rest of the complications that have accreted onto programming languages over time.<br>So RWR is a tiny notation for expressing rewrites as string operations — raw characters plus interpolation — and nothing else.<br>The trick is how it gets executed. A tool I called T2T calls OhmJS twice: once to transmogrify RWR source into JavaScript, and once to eval() that generated JavaScript into real semantics actions and run OhmJS again on the actual source. Two grammars, one eval(), bolted together. The whole T2T implementation came to about 26 lines plus 33 lines of supporting code, written in roughly an hour and a half.<br>That last detail is the part worth dwelling on, because it’s not really about RWR.<br>Code like this — quick, narrow, string-only, held together with eval() — is not production quality by any reasonable definition. But that’s the wrong yardstick. In the 21st century we have the luxury of writing at least two kinds of code:<br>Code for production release.

Code purely to speed up our own development workflow.

Different customers, different lifespans, different acceptable failure modes.<br>That wasn’t always an option. In the 20th century, CPU cycles and memory were expensive enough that almost all code had to justify itself against one yardstick: will this run efficiently and reliably for years. Under that constraint, “quick and disposable” wasn’t a real category. That economic pressure shaped what we assumed code had to be — including the assumption that all programming languages must operate synchronously and sequentially, like a CPU executing instructions one at a time. It’s so deep it barely feels like an assumption.<br>But it isn’t the only substrate, even historically. Prolog and relational programming lean on backtracking to search for solutions instead of dictating steps. Forth has its own calling convention built around an explicit stack. Atari’s Pong, in 1972, ran as discrete logic gates in massive asynchronous parallelism — no clock ticking through instructions, just circuits reacting to each other at once. “Synchronous and sequential” was always a choice, made for good reasons at the time, never the only option.<br>Once you accept that some code only has to serve you, for a short time, to save you effort, you stop needing that code to look like production code or run the way production code runs. RWR and T2T are a small example: a DSL held together with interpolation and eval(), built in ninety minutes, whose only job was to save me from writing JavaScript by hand. Bad way to build a shipped product. Exactly the right way to build a tool for myself, this week, for this problem. The tool was, indeed, built quickly, but I’ve been fruitfully using it for years.<br>The broader move is to notice how many other “assumed” constraints are leftover 20th-century economics, and ask what changes if you loosen them — not just for what you ship, but for the string-matching tools, ASTs, and little SCNs you build purely to make your own next project faster. We can afford better shovels now, and the shovels don’t have to be cathedrals.<br>Appendix - T2T

T2T is one of the tools in the PBP toolkit — once you install PBP, you have access to T2T.<br>Appendix RWR

RWR is part of T2T. This is the specification for RWR<br>Appendix - PBP

PBP tools<br>Appendix - Further About PBP

Towards Parts...

code programming like javascript eval simplification

Related Articles