MoreRSS

site iconTim BrayModify

ongoing is short for “ongoing fragmented essay. The unifying themes are Truth, Technology, and Business.
Please copy the RSS to your reader, or quickly subscribe to:

Inoreader Feedly Follow Feedbin Local Reader

Rss preview of Blog of Tim Bray

Because Algospeak

2026-03-06 04:00:00

Recently I read Because Internet by Gretchen McCulloch and Algospeak by Adam Aleksic. The language we speak (and text) to each other is at the core of who and what we are, and the Internet is the strongest among the forces that channel and fertilize its growth. So there’s scope for plenty of books on the subject. Both books educated and entertained, one made me angry.

The covers of “Because Internet” and “Algospeak”

Because Internet (2019)

Its approach is historical and its voice fairly uninflected. It smiles and argues, but it doesn’t ROFL nor does it YELL AT YOU. The history is longer, perhaps, than most people reading this have been online (or even alive). Ms McCulloch goes back to the days of BBSes (“bulletin-board systems”) and ListServs and IRC. Some of the jargon and formulations of those days live on; you’d be surprised.

Here’s her table of contents.

Table of Contents from “Because Internet”

The analysis is grounded in the formalisms of the author’s profession, academic linguistics. Nothing wrong with that.

Let’s look at a couple of her ideas, beginning with Chapter 1’s “Informal Writing”. A few of us, back in the late Eighties, noticed that computers in general and the then-nascent Internet in particular were driving a writing renaissance.

Before computers, a knowledge worker who had laboriously constructed essays in college quite likely wrote almost nothing for the rest of their working life. People talked face-to-face or on the phone, and dictated to secretaries. Written communication was seen as necessarily formal and disjoint from the way we spoke, or that we wrote in personal correspondence. Then, suddenly, everyone was sitting at a keyboard only seconds away from everyone else’s screen. McCulloch goes deep on this:

In the future, the era of writing between the invention of the printing press and the internet may come to be seen as an anomaly—an era when there arose a significant gap between how easy it was to be a writer versus a reader. An era when we collectively stopped paying attention to the informal, unedited side of writing and let typography become static and disembodied.

The internet didn’t create informal writing, but it did make it more common, changing some of our previously spoken interactions into near-real-time text exchanges.

From which all of this follows. It feels like a central insight. I suppose you could argue that centrality of informal text is fading in the face of short-form video. Maybe, it’s too soon to tell.

Then consider chapter 5, about emojis. Linguists obviously need to think about them because now they’re an integral part of written language. McCulloch’s insight is that they correspond almost exactly to gestures, the way we use our hands to add force to our speech. Obviously, for example, “👍”. Or when you’re talking about something completely loopy and you twirl your index finger by your ear? You meant “🤪”.

I offer the emoji story for flavor, an example of a linguist’s approach to what we’re doing to our language with our networks.

McCulloch has lots more of this stuff. I enjoyed Because Internet a lot, partly because I’m old and my memories stretch back to those BBS and IRC days and I had a front-row seat for the decades of linguistic seething and heaving. And also because I’m a Unicode geek.

Algospeak (2025)

The subtitle is “How Social Media Is Transforming the Future of Language”. OK, but… Social media is a fertile field for language evolution. Thing is, corporate social media discourse lives in the dire grip of the proprietors’ algorithms. And that’s where Adam Aleksic focuses. He treats all of them as a single opaque object, “The Algorithm”, which I think is fair because they all are designed with one goal: To maximize the effectiveness of human conversation at generating advertising revenue.

First, the Table of Contents.

Table of Contents from “Algospeak

Aleksic knows whereof he speaks: As “Etymology Nerd”, his aggregate following across TikTok, Instagram, and YouTube is over three million. He’s all about cool bits and pieces of linguistics, often Internet-specific usages. If I had the patience for podcasts I suppose his would be near the top of my list.

He really enjoys his work and has fun talking about some of Social Media’s more colorful linguistic extrusions; check that Table of Contents. I’m kind of old and I learned a lot about the words and emojis younger folk emit, and I think most folks, even those just out of their teens, would too. I’m on a Discord for a Major League Soccer team’s fans, and while it’s totally all-ages, I can say I am regularly less mystified than I was before I read Algospeak. For example, now I know what it means when someone tosses “💀” into a chat. Do you?

Aleksic isn’t averse to a little history himself. Looking back over the successive online-jargon volcanoes, he argues convincingly that two stand out as extra productive. First of all, the short-lived (but hot stuff at the time) Vine video platform. Second, the incel cesspool; sad but (apparently) true.

The Algorithm

Remember, it’s all about what advertisers want. And wow, do they ever want a lot of things. I’ll just touch on a few of Aleksic’s points.

First of all, they don’t want to find themselves next to downers. So if you want to talk about death or suicide or rape or racism or rage, you need to fool The Algorithm. Thus “unalive” and many other dodges. Of course, The Algorithm learns about them so you have to keep dodging. Neither side of this struggle can stay ahead for long.

Here’s another thing I didn’t know: Apparently written Chinese is particularly rich in techniques for euphemizing, making it easier for users of that language to evade, for a time, The Algorithm.

Partitioning people

Another big thing The Algorithm likes is grouping people into smaller and smaller baskets based on interests, generations, and many other criteria. This is because advertisers can aim very specific campaigns at just exactly the right cohort of people who are likely to buy what they’re selling. Here’s a quote; See how the language fills in behind advertisers’ pressure?

It doesn’t matter how much I label myself. If I’m a demisexual goblincore Gen Z Swiftie, I guarantee there are still others like me. The only thing these labels really change about me is that they make me easier to classify and market to. Ironically, true individuality may come out of a lack of labels and stories, because there’s greater freedom of expression with a blank slate. If everybody’s the “main character,” then nobody is.

Algospeak, unlike Because Internet, doesn’t limit itself to written language. One of its most compelling studies concerns the vocal techniques of podcasters and YouTubers. The finding is simple: It’s hard to build and hold an audience for your show unless you sound like MrBeast. No, really.

Anyhow, they’re both good books. Because Internet educated and entertained me. Algospeak is way more intense, intentionally more like the subject it addresses. Also it made me angry. I am a lover of human language and of its patterns of growth and mutation and simplification and complexification. Linguistics is one of the disciplines I regret not having chosen.

Aleksic makes it clear that there’s an amusing narrative about how the people living and speaking in the shade of the Algorithm can never defeat it, but they can still manage to get their messages across. But they shouldn’t have to struggle!

In fact, a few million of us have found a place to talk to each other that isn’t in The Algorithm’s shadow: Decentralized social media. Specifically the Fediverse (what people mean when they say “Mastodon”) and maybe the ATmosphere (same for “Bluesky”).

I want to see how language grows in a place where new forms arrive when they’re needed, to say new things that need to be said. Not to either serve or resist The Algorithm.

Kansas and AI

2026-02-28 04:00:00

Block announced that it’s cutting 40% of its workforce. It didn’t say it was replacing those people with GenAI. Not out loud. Jack Dorsey did say “I believe the majority of companies will reach the same conclusion and make similar structural changes.” Wall Street loved it, bidding up the share price by 24%. Which reminded me of Kansas in 2010.

The Kansas Experiment

As long as I can remember, a certain class of right-wing evangelists has preached that cutting taxes would stimulate business growth and everyone would come out ahead. There are a couple of problems with this theory. First, mainstream economists almost universally think it’s just wrong. Second, most of the people pushing it are rich and would benefit from the cuts.

Anyhow, in 2010 US Senator Sam Brownback won the race for governor of Kansas on what was then called the “Tea Party” program: Prosperity through tax cuts. Tea-party Republicans also won a large majority in the state legislature. Unsurprisingly they immediately did what they said they were going to do: Slashed a wide variety of taxes, some to zero.

The predicted prosperity failed to happen. The state government’s revenue plunged and it had to dig deep into rainy-day reserves just to keep the doors open. There were brutal cuts to policing, road repair, and schools. Also a nasty feedback loop: As the state’s fiscal position worsened, its credit rating fell and interest rates rose, leading to yet more brutal austerity measures.

Another result was that affluent Kansans made out like bandits; the cost of running the state was substantially transferred to the less financially fortunate.

In 2017, the legislature threw in their cards and repealed the tax cuts, overriding Brownback’s veto.

While this was a terrible experience for most Kansans, it is historically useful, because whenever you encounter a tax-cut nut (probably self-interestedly wealthy) you can say “But, Kansas!” Having said that, there are still plenty of those nuts, and they’ll tell you that the Kansas experiment failed because of one fine-tuning effort or another. That’s a position that’s hard to defend, though.

Sidebar: Trans oppression too

Before I move onto the AI angle, I gotta pause to acknowledge this week’s news story about the Kansas government’s vicious, brutal, and ignorant assault on trans people. To be clear, I think the shitty people who hate trans folk are aren’t necessarily the same shitty people as the shitty people who don’t want to contribute to the public good. But, something about Kansas seems to attract both flavors.

The GenAI experiment

The core value proposition of contemporary AI technology is exactly what Dorsey seems to think: Fire half your employees and profits will soar! If that’s true, the trillion dollars or so invested so far will seem like small potatoes. Since we don’t know if this will actually work, anyone who actually does it is conducting an experiment. Just like Sam Brownback did. Unsurprisingly, the investor class loves this experiment and is putting their money on it working.

To be fair, voices have been raised to argue that the tech sector is a special case: That following on feverish over-hiring during the Covid lockdown, they need to slash headcount anyhow, and are using AI as an excuse. For example John Gruber.

I personally am unconvinced, but even if they’re right, it’s irrelevant. The shareholding class won’t be able to see past that 24% payoff. So as of today, they’ll be yelling at every CEO on the planet to start pulling the mass-firing trigger. Or else.

I think I know how the experiment will turn out. Just like in Kansas, it’s not going to be fun.

Crocuses of 2026

2026-02-25 04:00:00

I’ve run early-spring pictures of these little purple guys almost every year since this blog’s birth in early 2003. Except for last year. Because we moved and the new place didn’t have any. Only now it does, and they’re (just barely) up. [Update: Up and open, too.]

Crocuses of February 2026

Long-time followers may note that they’re pale and fragile compared to the exuberant blossoms of previous years. Not sure why, but our new place faces north and there’s this enormous White Ash tree right in front of it, so they’re not getting as much sun as at the south-facing former joint.

Crocuses of February 2026

And also this is their first spring. We bought the bulbs and hired a professional with the right tools to jam them into the earth last autumn, between the big tree’s roots. So they really haven’t had a chance to get their own root systems going.

And finally, it really is the first day that’s bright and warm enough to get out the camera. Maybe they’ll be better in another few days. And quite likely next Spring.

Crocuses of February 2026

This would be the place to introduce whatever metaphor this year’s blossoms, fighting their way through the leaf cover in chilly air toward the sun, fit into, but I’m not gonna.

I, like many, am not dealing very well with what I see when I look at the world in either the big or the ultra-local landscapes. The world in tough shape and its worst people are making it worse. People I love are in ugly corners and not finding help.

But you know, the flowers, in their low-key way, look great and so does the tree, still in wintersleep. Today the sun was shining on them. It’ll be warmer and nicer soon.

Metaphors can go to hell. It’s just late-winter light on pale violet petals. Enjoy the moments you have with it.

Spring crocus, now open for business

Update: Now open for business.

Open Source and GenAI?

2026-02-17 04:00:00

I’ve been puttering away on my Quamina project since 2023. In the last few weeks GenAI has intervened. Quamina + Claude, Case 1 describes a series of Claude-generated human-curated PRs, most of which I’ve now approved and merged. Quamina + Claude, Case 2 considers quamina-rs, a largely-Claude-driven port from Go to Rust. Both of these stories seem to have happy endings and negligible downsides. So empirically, I can apply LLM technology usefully to software development. But should I?

Conclusions 1: Burn it with fire?

Let me be clear: In the big GenAI picture, I’m a contra. Why? I’ll pass the mike to Baldur Bjarnason, my favorite among GenAI’s blood enemies.: “AI” is a dick move. His tl;dr is something like “GenAI is environmentally devastating and has the goal of throwing millions of knowledge workers onto the street and is being sold by the worst people and is used for horrible applications and will increase society’s already-intolerable level of inequality!” To which I reply “Yes, yes, yes, yes, and yes.”

At the end of the day, the business goal of GenAI is to boost monopolist profits by eliminating decent jobs, and damn the consequences. This is a horrifying prospect (although I’m somewhat comforted by my belief that it basically won’t work and most of the investment capital is heading straight down the toilet).

But. All that granted, there’s a plausible case, specifically in software development, for exempting LLMs from this loathing.

First of all, size. JetBrains thinks that the world has 21 million or so software developers, i.e. less than 1% of the earth’s working population. Vanishingly small in the context of the lunatic tsumani of LLM overinvestment. Training and operating the models required for a market this small is rounding error measured on the Great GenAI Overbuild scale. There aren’t enough geeks to create a detectable bump in the global carbon load.

Another odious aspect of LLMs is RLHF, “Reinforcement Learning From Human Feedback”, which relies on underpaying Third-Worlders to polish the models’ outputs. My guess is that much less is required for code-oriented LLMs. The combination of the compiler and your unit tests provide good starter guardrails. Then skilled professional intervention is required to deal with the remaining misfires, as with those Quamina PRs.

Finally, it seems making billionaires into multibillionaires is intrinsic to GenAI dreams. But software-development tools won’t do that. Once again, the market is just too small. But even if it weren’t, consider this from Steve Yegge:

For this blog post, “Claude Code” means “Claude Code and all its identical-looking competitors”, i.e. Codex, Gemini CLI, Amp, Amazon Q-developer ClI, blah blah, because that’s what they are. Clones.

(GenAI, overbuilding wherever you look.) None of these products have moats and the chance that any of them become extractive monopolies is about zilch. Nobody’s ever built a major cash-cow on developer tooling

One reason is (*gasp*) Open Source. Does anybody doubt that in the near future, there will be entirely open-source versions of what Yegge means by “Claude”?

So, if you want to condemn the use of GenAI in software development, I think you need arguments other than the fact that it’s also being promoted for societally-toxic business purposes.

I have a few. But stand by, let me push that on the stack and turn to technology for a bit.

Conclusions 2: Engineering sanity?

Question: Can LLMs even participate in quality software engineering? Baldur doesn’t think so: “The gigantic, impossible to review, pull requests. Commits that are all over the place. Tests that don’t test anything. Dependencies that import literal malware. Undergraduate-level security issues. Incredibly verbose documentation completely disconnected from reality.”

I’m not saying that these pathologies can’t or don’t happen. But in my personal experience with Quamina, they didn’t. (Mind you, it’s a hobby project.)

And when they do happen, I would assume that mature open-source projects will use a network of trust, as big operations like Linux already do. PRs that don’t have the imprimatur of someone known to be clueful will be ignored. When I saw the first of those incoming Quamina PRs, I took the time for a serious look because I knew Rob and had seen evidence that he was technically competent. If I see an incoming PR that’s nontrivial and from some rando and doesn’t pass a 120-second sanity check, it’s unlikely to get any more attention.

In fact, some essentials don’t change. If you’re not requiring that PRs be clean and test coverage be good and code reviews not be skipped and dependencies be curated, you’re going to get a lousy result whether the upstream code is coming from a human or an LLM.

But it’d be naive to think that a big change in the shape of that upstream isn’t going to affect the profession.

Bottlenecks

Speaking from personal experience, reviewing the PRs from Claude&Rob was neither faster nor slower, easier nor harder, than what I’m used to pre-GenAI. The number of my disagreements with the diffs, and the amount of arguing it took to resolve them, was also about as usual. Which creates a big problem. Because if we can generate code a whole lot faster but review doesn’t speed up, all we’ve done is moved the bottleneck in the system.

Speaking of which, Armin Ronacher offers The Final Bottleneck, from which: “When one part of the pipeline becomes dramatically faster, you need to throttle input.” Think about that.

Burnout

Meanwhile, evidence is piling up that LLM-based software development is driving developers to overwork and burnout. Here’s a cool-eyed take from Harvard Business Review. Then there’s Steve Yegge’s frantic, overly-long The AI Vampire. But my favorite, and I think a must-read, is Siddhant Khare’s AI fatigue is real and nobody talks about it. From which: “AI reduces the cost of production but increases the cost of coordination, review, and decision-making. And those costs fall entirely on the human.”

The argument we’re hearing is that GenAI makes development more efficient. And more efficient is better. Until it’s not.

I’m not sure the profession I joined last century would attract me today. And on Mastodon, @GordWait said “At our office, we are noticing a huge drop in Comp Sci co-op applications. The next generation is convinced there’s no future in programming thanks to AI hype.”

Can and should

Here’s another conundrum. Suppose we can build a whole lot more stuff, faster. Should we? I don’t know about you, but I am regularly enraged at tools that work just fine popping up “wonderful new features” modals in front of what I’m trying to get accomplished. Also at damaging UI churn, driven by product managers trying to get promoted. It’s just not obvious that speeding up software development is, in the big picture, a good thing.

And I can’t help noting that every attempt to measure the productivity boost due to GenAI has shown zero (or worse) improvement. Of course, Claude’s cheering section will point out that those studies date to 2024 which is the stone age. Maybe they’re right.

Vampires

(In which I once again go all class-reductionist.) The real problem here is late-stage capitalism, and I think is best addressed in Yegge’s AI Vampires piece, from which I quote: “…dollar-signs appear in their [employers’] eyeballs, like cartoon bosses. I know that look. There’s no reasoning with the dollar-eyeball stare.” Yeah.

Thus the ancient question: cui bono? Assuming GenAI genuinely boosts productivity, who gets the benefits? Because the ownership class sure doesn’t think they should go to their newly-more-efficient employees.

But, what do I know?

I know that you gotta have test coverage or your software is an unmaintainable tangle of festering tech debt. I know you gotta have code review or your quality is on inexorable downhill drift. I don’t know how to build LLMs into a sane, sustainable software engineering culture. Nor what to do about capitalism’s AI Vampires.

And I absolutely do not believe the wild-eyed claims of 10× productivity gains, assuming we demand (as we should) that they’re sustainable at scale.

So, would I advise executives to tell software engineering shops to discard their culture in favor of vibe coding in the expectation of monstrous productivity wins? Nope. Vibe engineering, maybe. Centaurs, not reverse centaurs? Indeed.

But would I say “Stay away, don’t even look”? Nope. I’d probably suggest pointing the LLM at well-delimited non-strategic issues and optimizations, and emphasize no shortcuts on reviewing or CI/CD standards.

Also note that the GenAI apostles are at one in saying that this year’s tools are so much better than last year’s, and next year’s are guaranteed to be qualitatively still better! So why would you rush in and risk getting locked into soon-to-be-outmoded tooling?

Rob Sayre wrote “I would never bother to type out these patches by hand. But I read them all.” I probably wouldn’t have either and I read them too. And now Quamina is roughly twice as fast. Which is to say, I got good results on a hobby project. That’s not nothing.

But, also not conclusive. Once the AI bubble pops and we’ve recovered from the systemic damage, I think there’ll probably be a place for open-source LLM automation in developer toolkits.

But maybe not. Wouldn’t surprise me much, either way.

Quamina + Claude, Case 2

2026-02-15 04:00:00

Last time out I described a bunch of incremental-improvement Quamina PRs from a colleague working with Claude Opus. Today I want to talk about Rishi Baldawa’s quamina-rs, a Claude-based port of Quamina from Go to Rust. The next post is about where I stand on GenAI and code.

Anybody who cares about this kind of thing will appreciate Rishi’s write-ups, starting with The Agents Kept Going (also see Scaffolding for Agent Velocity). He doesn’t just say what he did, he draws lessons; good ones, I think.

Background

Rishi and I worked together at AWS, can’t remember the details, but after I left he took over what we called Ruler, now known as aws/event-ruler, Quamina’s ancestor. At the time I left it had been adopted by quite a number of AWS and Amazon services and various instances were processing, in aggregate, a remarkable number of millions of events per second. So he knows the territory.

As for quamina-rs, go read his blogs. I’ve got little to add, but here are a couple of juicy quotes: “…at some point while I was mindlessly kicking off these sessions, the agents started picking up open issues from the Go version and implementing them on their own.“ Also, “And I think that’s the thing worth saying plainly. It’s human to care. Agents don’t care. Automation doesn’t care. They need to be told what to care about, and even then they’ll misbehave the moment you look away…”

Both these stories ended with useful results. So empirically, you can get useful results by applying GenAI to the process of code construction.

Yay. I guess. But there are a lot of smart people who think this whole LLM-fueled coding direction is irremediably toxic. I’m not sure they’re wrong.

Quamina + Claude, Case 1

2026-02-07 04:00:00

With 47 years of coding under my belt, and still a fascination for the new shiny, obviously I’m interested what role (if any) GenAI is going to play in the future of software. But not interested enough to actually acquire the necessary skills and try it out myself. Someday, someday. Didn’t matter; two other people went ahead without asking and applied Claude to my current code playground, Quamina. Here’s the first story. I’m going to go ahead and share it even though it will make people mad at me.

Why share?

Because our profession’s debate on this topic is simultaneously ridiculous and toxic. No meaningful dialogue seems possible between the Gas Town-and-Moltbook faction and the “AI” is a dick move camp. So, I’m not going to join in today. This is pure anecdata: What happened when Rob applied Claude to Quamina. I’m going to avoid rhetoric (in the linguistic sense, language designed to convince) and especially polemic (language designed to attack). I promise to have conclusions before too long, just not today.

What happened was…

There’s this guy Rob Sayre, I’ve known him for many years, even been in the same room once or twice, in the context of IETF work. I’ve never previously collaborated on code with him. Starting in mid-January, he’s sent a steady flow of PRs, most of which I eventually accept and merge.

The net result is that Quamina is now roughly twice as fast on several benchmarks designed to measure typical tasks.

Technical details

The details of what Quamina is and does are in the README. For this discussion, let’s ignore everything except to say that it’s a Go library and consider its two most important APIs. AddPattern() adds a Pattern (literal or regexp) to an instance, and MatchesForEvent considers a JSON blob and reports back which Patterns it matched. It’s really fast and the relationship is pleasingly weak between the number of Patterns that have been added and the matching speed.

Quamina is based around finite automata (both deterministic and nondeterministic) and the rest of this technical-details section will throw around NFA and DFA jargon, sorry about that.

For code like this that is neither I/O-bound nor UI-centric, performance is really all about choosing the right algorithms. Once you’ve done that, it’s mostly about memory management. Obviously in Quamina, the AddPattern call needs to allocate memory to hold the finite automata. But I’d like it if the MatchesForEvent didn’t.

Go’s only built-in data structures are “map” i.e. hash table, and “slice” i.e. appendable array. (For refugees from Java, with its dozens of flavors of lists and hashes, this is initially shocking, but most Go fans come to the conclusion that Go is right and Java is wrong.) In really well-optimized code, you’d like to see all the time spent either in your own logic or in appending to slices and updating maps.

In less-well-optimized code, the profiler will show you spending horrifying amounts of time in runtime routines whose names include “malloc”, and in the garbage collector. Now, both maps and slices grow automatically as needed, which is nice, except when you’re trying to minimize allocation. It turns out that slices have a capacity, and as long as the number of things you append is less than the capacity, you won’t allocate, which is good. Thus, there are two standard tricks in the inventory of 100% of people who’ve optimized Go code:

  1. When you make a new slice, give it enough capacity to hold everything you’re going to be adding to it. Yes, this can be hard because you’re probably using it to store input data of unpredictable size, thus…

  2. After you’ve made a new slice, keep it around, clear it after each input record, and its capacity will naturally grow until it gets to be big enough that it fits all the rest of the records, then you’ll never allocate again.

Those PRs

Background: Quamina is equipped with what I think is a pretty good unit-test suite, and multiple benchmarks.

I started getting Rob’s PRs and initially, 100% of them were finding ways along both of those well-trodden map-and-slice paths, in places where I hadn’t noticed the opportunity. They were decent PRs, well-commented, sensible code, no loss of test coverage. After I asked to see benchmark runs to prove the gains weren’t just theoretical, they started including benchmark runs. I’ve found a few things to push back on but Rob and I had no problem sorting those out.

At the end of the day I had no qualms about merging them, but I did find myself wondering how they were built. So I asked.

Workflow

Rob had told me right away on the first one that these were substantially Claude-generated. I asked him for his workflow and part of what he said was “I might say ‘let's do some profiles of memory and CPU on this benchmark, on main and on this branch.’ It will come up with good and bad ideas, then I pick them.”

Also: “What might be counter-intuitive is that I can context switch really quickly with it. So, you leave a comment, and I just tell Claude to fix that, because you are correct. Sometimes I go in and hand edit, but usually it gets close or perfect (what they call a "one-shot"). But I just have the conversation open, so I just pick up where we left off.”

Here’s a sample of Claude talking to Rob. You may have to enlarge it.

Dialogue with Claude

Not just the same-old

Then I got a surprise, because Claude and Rob spotted two pretty big improvements that aren’t on the standard list. First: To traverse an NFA, for each state you have to compute its “epsilon closure”, the set of other states you can get to transitively following epsilon transitions. I had already built a cache so that as you computed them, they got remembered. C&R pointed out “Epsilon closures are a property of the automaton structure, not the input data. Once a pattern is added and the NFA is built, the epsilon closure for any given state is fixed and never changes.” So you might as well compute it and save it when you build the NFA.

This is even better than it sounds, because (for good reasons following from Quamina’s concurrency model) my closure caches were per-thread, while the new epsilon closures were global, stored just once for all the threads. Not bad, and not trivial.

Second, when you’re computing those closures, you have to memo-ize the key functions to avoid getting caught in NFA loops. I’d done this with a set, which in Go you implement as map[whatever]bool. R&C figured out that if you gave each state a “closure generation” integer field and maintained a global closure-generation value, you could dodge the necessity for the set at the cost of one integer per state. The benchmarks proved it worked.

As I wrote this piece, another PR arrived with a stimulating title: “kaizen: allocation-free on the matching path”.

Kaizen?

It’s the idea that you make things substantially better by successively introducing small improvements. We try to use the term to tag Quamina PRs that change no semantics but just make performance better or more reliable or whatever.

But GenAI is bad!?!

Yes, so they say. Go re-read that dick-move polemic.

But, I’m going to leave this little case study conclusion-free for a bit because there are two follow-up pieces. Next, the story of quamina-rs, a Claude-drive port of Quamina to Rust. Finally, Open Source and GenAI?.