2026-02-04 04:00:00
Welcome to the first Long Links of this so-far-pretty-lousy 2026. I can’t imagine that anyone will have time to take in all of these, but there’s a good chance one or two might brighten your day.
Thomas Piketty is always right. For example, Europe, a social-democratic power.
Lying is wrong. Conservatives do it all the time. To be fair, that piece is about the capital-C flavor, as in the Canadian Tories. But still.
Clothing is open-source: “If you slice the different parts off with a seamripper, lay them all down, trace them on new fabric, cut them out, and stitch them back together, you can effectively clone and fork garments.” From Devine Lu Linvega.
The Universe is weird. The Webb telescope keeps showing astronomers things that shouldn’t be there. For example, An X-ray-emitting protocluster at z ≈ 5.7 reveals rapid structure growth; ignore the title and read the Abstract and Main sections. With pretty pictures!
One time in Vegas, I was giving a speech, something about cloud computing, and was surprised to find the venue an ornate velvet-lined theater. I found out from the staff, and then relayed to the audience, that the last human before me to stand on this stage in front of an audience had been Willie Nelson. I was tempted to fall to my knees and kiss the boards. How Willie Nelson Sees America, from The New Yorker, is subtitled “On the road with the musician, his band, and his family” but it ends up being the kernel of a good biography of an interesting person. Bonus link; on YouTube, Willie Nelson - Teatro, featuring Daniel Lanois & Emmylou Harris, Directed by Wim Wenders. Strong stuff.
Speaking of recorded music, check out Why listening parties are everywhere right now. Huh? They are? As a deranged audiophile, sounds like my kind of thing. I’d go.
When I was working at AWS in downtown Vancouver back starting in 2015, a lot of our junior engineers lived in these teeny-tiny little one-room-tbh apartments. It worked out pretty well for them, they were affordable and an easy walk from the office and these people hadn’t built up enough of a life to need much more room. For a while this trend of so-called-“studio” flats was the new hotness in Vancouver and I guess around quite a bit of the developed world. Us older types with families would look at the condo market and tell each other “this is stupid”.
We were right. The bottom is falling out and they’re sitting empty in their thousands. And not just the teeniest either, the whole condo business is in the toilet. It didn’t help that for a few years all the prices went up every year (until they didn’t) and you could make serious money flipping unbuilt condos, so lots of people did (until they didn’t).
Anyhow, here’s a nice write-up on the subject: ‘Somewhere to put worker bees’: Why Canada's micro-condos are losing their appeal. (From the BBC, huh?)
Sorry, I can’t not relay pro- and anti-GenAI posts, because that conversation is affecting all our lives just now. I am actually getting ready to decloak my own conclusions, but for the moment I’m just sharing essays on the subject that strike me as well-written and enjoyable for their own sake. Thus ‘AI' is a dick move, redux from Baldur Bjarnason. Boy, is he mad.
Sam Ruby has been doing some extremely weird shit, running Rails in the browser, as in without even a network connection or a Ruby runtime. Yes, AI was involved in the construction.
There’s this programming language called Ivy that is in the APL lineage; that acronym will leave young’uns blank but a few greying eyebrows will have been raised. Anyhow, Implementing the transcendental functions in Ivy is delightfully geeky, diving deep with no awkwardness. By no less than Rob Pike.
Check out Mike Swanson’s Backseat Software. That’s “backseat” as in “backseat driver”, which today’s commercial software has now, annoyingly, become. This piece doesn’t make any points that I haven’t heard (or made myself) elsewhere, but it pulls a lot of the important ones together in a well-written and compelling package. Recommended.
Old Googler Harry Glaser reacts with horror to the introduction of advertising by OpenAI, and makes gloomy predictions about how it will evolve. His predictions are obviously correct.
The title says it: Discovering a Digital Photo Editing Workflow Beyond Adobe. It’d be a tough transition for me, but the relationship with Adobe gets harder and harder to justify.
Khelsilem is one of the loudest and clearest voices coming out of the Squamish nation, one of the larger and better-organized Indigenous communities around here.
There has been a steady drumbeat of Indigenous litigation going on for decades as a consequence of the fact that the British colonialists who seized the territory in what we now call British Columbia didn’t bother to sign treaties with the people who were already there, they just assumed ownership. The Indigenous people have been winning a lot of court cases, which makes people nervous.
Anyhow, Khelsilem’s The Real Source of Canada's Reconciliation Panic covers the ground. I’m pretty sure British Columbians should read this, and suspect that anyone in a jurisdiction undergoing similar processes should too.
There’s this thing called the Resonant Computing Manifesto, whose authors and signatories include names you’d probably recognize. Not mine; the first of its Five Principles begins with “In the era of AI…” Also, it is entirely oblivious to the force driving the enshittification of social-media platforms: Monopoly ownership and the pathologies of late-stage capitalism.
Having said that, the vision it paints is attractive. And having said that, it’s now featured on the flags waved by the proponents of ATProto, which is to say Bluesky. See Mike Masnick’s ATproto: The Enshittification Killswitch That Enables Resonant Computing (Mike is on Bluesky Corp’s Board). That piece is OK but, in the comments, Masnick quickly gets snotty about the Fediverse and Mastodon, in a way that I find really off-putting. And once again, says nothing about the underlying economic realities that poison today’s platforms.
I want to like Bluesky, but I’m just too paranoid and cynical about money. It is entirely unclear who is funding the people and infrastructure behind Bluesky, which matters, because if Bluesky Corp goes belly-up, so does the allegedly-decentralized service.
On the other hand, Blacksky is interesting. They are trying to prove that ATProto really can be made decentralized in fact not just in theory. Their ideas and their people are stimulating, and their finances are transparent. I’ll be moving my ATProto presence to Blacksky when I get some cycles and the process has become a little more automated.
The cryptography community is working hard on the problem of what happens should quantum computers ever become real products as opposed to over-invested fever dreams. Because if they ever work, they can probably crack the algorithms that we’ve been using to provide basic Web privacy.
The problem is technically hard — there are good solutions though — and also politically fraught, because maybe the designers or standards orgs are corrupt or incompetent. It’s reasonable to worry about this stuff and people do. They probably don’t need to: Sophie Schmieg dives deep in ML-KEM Mythbusting.
Here’s one of the most heartwarming things I’ve read in months: A Community-Curated Nancy Drew Collection. Reminder: The Internet can still be great.
John Lanchester’s For Every Winner a Loser, ostensibly a review of two books about famous financiers, is in fact an extended howl of (extremely instructive) rage against the financialization of everything and the unrelenting increase in inequality. What we need to do is to take the ill-gotten gains away from these people and put it to a use — any use — that improves human lives.
I talk a lot about late-stage capitalism. But Sven Beckert published a 1,300-page monster entitled Capitalism; the link is to a NYT review and makes me want to read it..
Charlie Stross, the sci-fi author, likes webtoons and recommends a bunch. Be careful, do not follow those links if you’re already short of time. Semi- or fully-retired? Go ahead!
I have history with dictionaries. For several years of my life in the late Eighties, I was the research project manager for the New Oxford English Dictionary project at the University of Waterloo. Dictionaries are a fascinating topic and, for much of the history of the publishing industry, were big money-makers; they dominate any short list of the biggest-selling books in history. Then came the Internet.
Anyhow, Louis Menand’s Is the Dictionary Done For? starts with a review of a book by Stefan Fatsis entitled Unabridged: The Thrill of (and Threat to) the Modern Dictionary which I haven’t read and probably won’t, but oh boy, Menand’s piece is big and rich and polished and just a fantastic read. If, that is, you care about words and languages. I understand there are those who don’t, which is weird. I’ll close with a quote from Menand:
“The dictionary projects permanence,” Fatsis concludes, “but the language is Jell-O, slippery and mutable and forever collapsing on itself.” He’s right, of course. Language is our fishbowl. We created it and now we’re forever trapped inside it.
2026-01-21 04:00:00
There’ve been a few bugfixes and optimizations since 1.5, but the headline is: Quamina now knows regular expressions. This is roughly the fourth anniversary of the first check-in and the third of v1.0.0. (But I’ve been distracted by family health issues and other tech enthusiasms.) Open-source software, it’s a damn fine hobby.
Did I mention optimizations? There are (sob) also regressions; introducing REs had measurable negative impacts on other parts of the system. But it’s a good trade-off. When you ship software that’s designed for pattern-matching, it should really do REs. The RE story, about a year long, can be read starting here.
About 18K lines of code (excluding generated code), 12K of which are unit tests. The RE feature makes the tests run slower, which is annoying.
Adding Quamina to your app will bulk your executable size up by about 100K, largely due to Unicode tables.
There are a few shreds of AI-assisted code, none of much importance.
A Quamina instance can match incoming data records on my 2023 M2 Mac at millions per second without much dependence on how many patterns are being matched at once. This assumes not too many horrible regular expressions. That’s per-thread of course, and Quamina does multithreading nicely.
The open issues are modest in number but some of them will be hard.
I think I’m going to ignore that list for a while (PRs welcome, of course) and work on optimization. The introduction of epsilon transitions was required for regular expressions, but they really bog the matching process down. At Quamina’s core is the finite-automaton merge logic, which contains fairly elegant code but generally throws up its hands when confronted with epsilons and does the simplest thing that could possibly work. Sometimes at an annoyingly slow pace.
Having said that, to optimize you need a good benchmark that pressures the software-under-test. Which is tricky, because Quamina is so fast that it’s hard to to feed it enough data to stress it without the feed-the-data code dominating the runtime and memory use. If anybody has a bright idea for how to pull together a good benchmark I’d love to hear it. I’m looking at b.Loop() in Go 1.24, any reason not to go there?
It occurs to me that as I’ve wrestled with the hard parts of Quamina, I’ve done the obvious thing and trawled the Web for narratives and advice. And, more or less, been disappointed. Yes, there are many lectures and blogs and so on about this or that aspect of finite automata, but they tend to be mathemagical and theoretical and say little about how, practically speaking, you’d write code to do what they’re talking about.
The Quamina-diary ongoing posts now contain several tens of thousands of words. Also I’ve previously written quite a bit about Lark, the world’s first XML parser, which I wrote and was automaton-based. So I think there’s a case for a slim volume entitled something like Finite-state Automata in the Code Trenches. It’d be a big money-maker, I betcha. I mean, when Apple TV brings it to the screen.
Let’s be honest. While the repo has quite a few stars, I truly have no idea who’s using Quamina in production. So I can’t honestly claim that this work is making the world better along any measurable dimension.
I don’t much care because I just can’t help it. I love executable abstractions for their own sake.
2026-01-15 04:00:00
Confession: My title is clickbait-y, this is really about building on the Unicode Character Database to support character-property regexp features in Quamina. Just halfway there, I’d already got to 775K lines of generated code so I abandoned that particular approach. Thus, this is about (among other things) avoiding those 1½M lines. And really only of interest to people whose pedantry includes some combination of Unicode, Go programming, and automaton wrangling. Oh, and GenAI, which (*gasp*) I think I should maybe have used.
I’m talking about regexp incantations like [\p{L}\p{Zs}\p{Nd}], which matches anything that Unicode classifies
as a letter, a space, or a decimal number. (Of course, in Quamina “\” is “~”
for excellent reasons, so that reads
[~p{L}~p{Zs}~p{Nd}].)
(I’m writing about this now because I just launched a PR to enable this feature. Just one more to go before I can release a new version of Quamina with full regexp support, yay.)
To build an automaton that matches something like that, you have to find out what the character properties are. This information comes from the Unicode Character Database, helpfully provided online by the Unicode consortium. Of course, most programming languages have libraries that will help you out, and that includes Go, but I didn’t use it.
Unfortunately, Go’s library doesn’t get updated every time Unicode does. As of now, January 2026, it’s still stuck at Unicode 15.0.0, which dates to September 2023; the latest version is 17.0.0, last September. Which means there are plenty of Unicode characters Go doesn’t know about, and I didn’t want Quamina to settle for that.
So, I fetched and parsed the famous master file from
www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt.
Not exactly rocket science, it’s a flat file with ;-delimited fields, of which I only cared about the first
and third. There are some funky bits, such as the pair of nonstandard lines indicating that the Han characters occur
between U+4E00 and U+9FFF inclusive; but still not really taxing.
The output is, for each Unicode category, and also for each category’s complement (~P{L} matches everything
that’s not a letter; note the capital P), a list of pairs of code points, each pair indicating a subset
of the code space where that category applies. For example, here’s the first line of character pairs with category C.
{0x0020, 0x007e}, {0x00a0, 0x00ac}, {0x00ae, 0x0377},
How many pairs of characters, you might wonder? There are 37 categories and it’s all over the place but adds up to a lot. The top three categories are L with 1,945 pairs, Ll at 664, and M at 563. At the other end are Zl and Zp, both with just 1. The total number of pairs is 14,811, and the generated Go code is a mere 5,122 lines.
Turning these creations into finite automata was straightforward: I already had the code to handle regexps like
[a-zA-Z0-9], logically speaking the same problem. But, um, it wasn’t fast. My favorite unit test, an exercise in
sample-driven development with 992 regexps,
suddenly started taking multiple seconds, and my whole unit-test suite expanded from around ten seconds to over twelve; since I
tend to run the unit tests every time I take a sip of coffee or scratch my head or whatever, this was painful. And it occurred to
me that it would be painful in practice to people who want for some good reason or another to load up a bunch of
Unicode-property patterns into a Quamina instance.
So, I said to myself, I’ll just precompute all the automata and serialize them into code. And now we get to the title of this essay; my data structure is a bit messy and ad-hoc and just for the categories, before I got to the complement versions, I was generating 775K lines of code.
Which worked! But, it was 12M in size and while Go’s runtime is fast, there was a painful pause while it absorbed those data structures on startup. Also, opening the generated file regularly caused my IDE (Goland) to crash. And I was only halfway there. The whole approach was painful to work with so I went looking for Plan B.
The code that generates the automaton from the code point pairs is pretty well the simplest thing that could possibly work and it was easy to understand but burned memory like crazy. So I worked for a bit on making it faster and cheaper, but so far have found no low-hanging fruit.
I haven’t given up on that yet. But in the meantime, I remembered Computer Science’s general solution for all performance problems, by which I mean caching. So now, any Quamina instance will compute the automaton for a Unicode property the first time it’s used, then remember it. So now Quamina’s speed at adding Unicode-property regexps to an instance has increased from 135/second to 4,330, a factor of thirty and Good Enough For Rock-n-Roll.
It’s worth pointing out that while building these automata is a heavyweight process, Quamina can use them to match input messages at its typical rates, hundreds of thousands to millions per second. Sure, these automata are “wide”, with lots of branches, but they’re also shallow, since they run on UTF-8 encoded characters whose maximum length is four and average length is much less. Most times you only have to take one or two of those many branches to match or fail.
This particular segment of the Quamina project included some extremely routine programming tasks, for example fetching and parsing UnicodeData.txt, computing the sets of pairs, generating Go code to serialize the automata, reorganizing source files that had become bloated and misshapen, and writing unit tests to confirm the results were correct.
Based on my own very limited experience with GenAI code, and in particular after reading Marc Brooker’s On the success of ‘natural language programming’ and Salvatore (“antirez”) Sanfilippo’s Don't fall into the anti-AI hype, I guess I’ve joined the camp that thinks this stuff is going to have a place in most developers’ toolboxes.
I think Claude could have done all that boring stuff, including acceptable unit tests, way faster than I did. And furthermore got it right the first time, which I didn’t.
So why didn’t I use Claude? Because I don’t have the tooling set up and I was impatient and didn’t want to invest the time in getting all that stuff going and improving my prompting skills. Which reminds me of all the times I’ve been trying to evangelize other developers on a better way to do things and was greeted by something along the lines of “Fine, but I’m too busy right now, I’ll just going on doing things the way I already know how to.”
Does this mean I’m joining the “GenAI is the future and our investments will pay off!” mob? Not in the slightest. I still think it’s overpriced, overhyped, and mostly ill-suited to the business applications that “thought leaders” claim for it. That word “mostly” excludes the domain of code; as I said here, “It’s pretty obvious that LLMs are better at predicting code sequences than human language.”
And, as it turns out, the domain of Developer Tools has never been a Big Business by the standards of GenAI’s promoters. Nor will it ever be; there just aren’t enough of us. Also, I suspect it’ll be reasonably easy in the near future for open-source models and agents to duplicate the capabilities of Claude and its ilk.
Speaking personally, I can’t wait for the bubble to pop.
After I ship the numeric-quantifier feature, e.g. a{2-5}, Quamina’s regexp support will be complete and if no
horrid bugs pop up I’ll pretty quickly release Quamina 2.0. Regexps in pattern-matching software are a qualitative difference-maker.
After that I dunno, there are lots more interesting features to add.
Unfortunately, a couple years into my Quamina work, I got distracted by life and by other projects, and ignored it. One result is that so did the other people who’d made major contributions and provided PR reviews. I miss them and it’s less fun now. We’ll see.
2026-01-02 04:00:00
I’m just landing a
chonky PR in
Quamina whose effect is to enable the + and * regexp
features. As in my
last chapter, this is a disorderly war story not an essay, and
probably not of general interest. But
as I said then, the people who care about coercing finite automata into doing useful things at scale are My People (there are
dozens of us).
As I write this, I’m sitting in the same couch in my Mom’s living room in Saskatchewan where, on my first Christmas after joining AWS, I got the first-ever iteration of this software to work. That embryo’s mature form is available to the world as aws/event-ruler. (Thanks, AWS!) Quamina is its direct descendent, which means this story is entering its twelfth year.
Mom is now 95 and good company despite her failing memory. I’ve also arrived at a qualitatively later stage of life than in 2014, but would like to report back from this poorly-lit and often painful landscape: Executable abstractions are still fun, even when you’re old.
Anyhow, the reason I’m writing all this stuff isn’t to expound on the nature of finite automata or regular expressions, it’s to pass on lessons from implementing them.
In a previous episode I used the phrase Sample-driven development to describe my luck in digging up 992 regexp test cases, which reduced task task from intimidating to approachable. I’ve never previously had the luxury of wading into a big software task armed with loads of test cases written by other people, and I can’t recommend it enough. Obviously you’re not always going to dig this sort of stuff up, but give it a sincere effort.
I decomposed regular expressions into ten unique features, created an enumerated type to identify them, and implemented them by ones and twos. Several of the feature releases used techniques that turned out to be inefficient or just wrong when it came to subsequent features. But they worked, they were useful, and my errors nearly all taught me useful lessons.
Having said that, here’s some cool output that combines this lesson and the one above, from the unit test that runs those test cases. Each case has a regexp then one or more samples each of strings that should and shouldn’t match. I instrumented the test to report the usage of regexp features in the match and non-match cases.
Feature match test counts: 32 '*' zero-or-more matcher 27 () parenthetized group 48 []-enclosed character-class matcher 7 '.' single-character matcher 29 |-separated logical alternatives 16 '?' optional matcher 29 '+' one-or-more matcher Feature non-match test counts: 45 '+' one-or-more matcher 24 '*' zero-or-more matcher 31 () parenthetized group 49 []-enclosed character-class matcher 6 '.' single-character matcher 32 |-separated logical alternatives 21 '?' optional matcher
Of course, since most of the tests combine multiple features, the numbers for all the features get bigger each time I implement a new one. Very confidence-building.
This is the classic nineteen-sixties regular-expression implementation by Ken Thompson, described in Wikipedia here and (for me at least) more usefully, in a storytelling style by Russ Cox, here.
On several occasions I rushed ahead and implemented a feature without checking those sources, because how hard could it be? In nearly every case, I had problems with that first cut and then after I went and consulted the oracle, I could see where I’d gone wrong and how to fix it.
So big thanks, Ken and Russ.
In some particularly nasty regular expressions that
combine [] and ? and + and *, you can
get multiple states connected in complicated ways with epsilon links.
In Thompson’s Construction, traversing an NFA transitions not just from one state to another but from a current set of states
to a next set, repeat until you match or fail. You also compute epsilon closures as you go along; I’m skipping over details
here. The problem was that traversing these pathologically complex regexps with a sufficiently long string was leading to an
exponential explosion in the current-states and next-states sizes — not a figure of speech, I mean
O(2N). And despite the usage of the word “set” above, these weren’t, they contained endless
duplicates.
The best solution would be to study the traversal algorithm and improve it so it didn’t emit fountains of dupes. That would be hard. The next-best would to turn these things into actual de-duped sets, but that would require a hash table right in the middle of the traversal hot spot, and be expensive.
So what I did was to detect whenever the next-steps list got to be longer than N, sorted it, and crushed out all the dupes. As I write, N is now 500 based on running benchmarks and finding a value that makes number go down.
The reason this is good engineering is that the condition where you have to crush the list almost never happens, so in the
vast majority of cases the the only cost is an if len(nextSteps)>N comparison. Some may find this approach
impure, and they have a point. I would at some point like to go back and find a better upstream approach. But for now it’s still
really fast in practice, so I sleep soundly.
I’ve written before about my struggles with the benchmark where I merge 12,959 wildcard patterns together. Back before I was doing epsilon processing correctly, I had a kludgey implementation that could match patterns in the merged FA at typical Quamina speeds, hundreds of thousands per second. With correct epsilon general-purpose epsilon handling, I have so far not been smart enough to find a way to preserve that performance. With the full 13K patterns, Quamina matches at less than 2K/second, and with a mere thousand, at 16K/second. I spent literally days trying to get better results, but decided that it was more valuable to Quamina to handle a large subset of regular expressions correctly than to run idiotically large merges at full speed.
I’m pretty sure that given enough time and consideration, I’ll be able to make it better. Or maybe someone else who’s smarter than me can manage it.
The still-unimplemented regexp features are:
{lo,hi} : occurrence-count matcher
~p{} : Unicode property matcher
~P{} : Unicode property-complement matcher
[^] : complementary character-class matcher
Now I’m wondering what to do next. [^] is pretty easy I think and is useful, also I get to invert a
state-transition table. The
{lo,hi} idiom shouldn’t be hard but I’ve been using regexps for longer than most of you have been alive and have
never felt the need for it, thus I don’t feel much urgency. The Unicode properties I think have a good fun factor just because
processing the Unicode character database tables is cool. And, I’ve used them.
[Update: the [^] thing took a grand total of a couple of hours to build and test. Hmm, what next?]
I tell people I keep working on code for the sake of preserving my mental fitness. But mostly I do it for fun. Same for writing about it. So, thanks for reading.
2025-12-19 04:00:00
What happened was, a faucet started dripping. And then I managed to route around the malignant machineries of late-stage capitalism. These days, that’s almost always a story worth telling.
Normally, faced with a drip, we’d pull out the old cartridge, take it to the hardware store, and buy another to swap in. But the fixture in our recently-acquired place was kind of exotic and abstract and neither of us could figure it out. We were gloomy because we’ve had terrible luck over the years with the local plumbing storefronts. So…
Our neighborhood has an online chat; both sides of the streets in a square around a single city block. This is our first experience with such a thing. I gather that these don’t always work out well, but this one has been mostly pretty great.
So at 9AM I posted “Hey folks, looking for a plumber recommendation” and by ten there were three.
[Late-stage capital: “You’re supposed to ask the AI in your browser. It’ll provide a handy link to a vendor based on geography and reviews but mostly advertising spend. Why would you want to talk to other people?”]
I picked a neighbor’s suggestion, first name Thomas, and called the number. “Thomas here” on the second ring. I explained and he said “What’s the brand name? If it’s one of those Chinese no-names I probably have to replace the whole thing.” I said “No idea, but I’ll take a picture and send it to you.”
Turns out the brand was Riobel, never heard of them. I texted Thomas a picture and he got right back to me: “That’s high-end, it’s got a lifetime warranty. I’ll come by a little after 5 and take it out. Their dealer is in PoCo (an outer suburb) and I live out there, so I can swap it.”
[Late-stage capital: “You’re supposed to engage with the chatbot on the site we sent you to, which will integrate with your calendar and arrange for a diagnostic visit a week from Wednesday. You could call them but you’d be in voice-menu hell and eventually end up at the same chatbot.”]
When Thomas showed up, with a sidekick, he was affable and obviously competent. Within five minutes I was glad I’d called for help; that faucet’s construction was highly non-obvious. Thomas knew what he was doing and it still took him the best part of a half-hour to get it all disassembled and the cartridge extracted.
The next morning, a text from Thomas: “Bad news. That part is back-ordered till May at Riobel’s dealer. We can maybe get it online but you’d have to pay.” He attached a screenie of a Web search for the part number; there were several online vendors.
It’s irritating that the “lifetime warranty” doesn’t seem to be helping me, but to be fair, the part was initially installed in 2011.
[Late-stage capital: “Lifetime warranty? Huh? Oh, of course you mean our VIP-class subscription offering, that’s monthly with a discount for annual up-front payment.” (And the part would still be back-ordered.)]
High-end plumbing parts are expensive. But one of Thomas’ recommendations, Kolani Kitchen and bath, was asking less.
They had a phone number on their Web site so I called it and the voice menu only had three options: Location, opening hours, and Operator. The operator was an intelligent human and picked up right away. “Hi, I’m looking at ordering a cartridge and wanted to see if you had it in stock.” “Gimme the part number?” I did and she went away for a couple of minutes and came back “Yeah, it’s in stock.” So I ordered it and I have a tracking number.
[Late-stage capital: “There aren’t supposed to be independent dealers; the manufacturer has taken PE money and eliminated the middlemen to better capture all the value-add. Or maybe there’ll be a wholesaler, but just one, because another PE rolled up all the distributors to maximize pricing power. Either way, you won’t be able to get a human on the line.”]
Next morning, I got an email that my order had been canceled. So I called that intelligent operator and she said “I was going to email you. Our system won’t take payment if the billing and delivery addresses are different. Sorry. If you’re in a hurry you could do an e-transfer?” (In Canada, all the banks are in a payments federation that makes this dead easy.) So I did and the part has shipped.
[Late-stage capital: “What? If you’d used our Integrated online payment offering, it would all just work. What if it doesn’t, you ask? Yeah, sucks to be you in that situation, of course there’d be nobody you could talk to about that.”]
Thomas came by again to put the old cartridge back in for now and said “This thing, don’t worry about a drip, it’s not fast and it probably won’t get worse. Text me when the new part gets in.”
It won’t be missed when it’s gone.
2025-12-08 04:00:00
The GenAI bubble is going to pop. Everyone knows that. To me, the urgent and interesting questions are how widespread the damage will be and what the hangover will feel like. On that basis, I was going to post a link on Mastodon to Paul Krugman’s Talking With Paul Kedrosky. It’s great, but while I was reading it I thought “This is going to be Greek to people who haven’t been watching the bubble details.” So consider this a preface to the Krugman-Kedrosky piece. If you already know about the GPU-fragility and SPV-voodoo issues, just skip this and go read that.
When companies buy expensive stuff, for accounting purposes they pretend they haven’t spent the money; instead they “depreciate” it over a few years. That is to say, if you spent a million bucks on a piece of gear and decided to depreciate it over four years, your annual financials would show four annual charges of $250K. Management gets to pick your depreciation period, which provides a major opening for creative accounting when the boss wants to make things look better or worse than they are.
Even when you’re perfectly honest it can be hard to choose a fair figure. I can remember one of the big cloud vendors announcing they were going to change their fleet depreciation from three to four years and that having an impact on their share price.
Depreciation is orderly whether or not it matches reality: anyone who runs a data center can tell you about racks with 20 systems in them that have been running fine since 2012. Still, orderly is good.
In the world of LLMs, depreciation is different. When you’re doing huge model-building tasks, you’re running those expensive GPUs flat out and red hot for days on end. Apparently they don’t like that, and flame out way more often than conventional computer equipment. Nobody who is doing this is willing to come clean with hard numbers but there are data points, for example from Meta and (very unofficially) Google.
So GPUs are apparently fragile. And they are expensive to run because they require huge amounts of electricity. More, in fact, than we currently have, which is why electrical bills are spiking here and there around the world.
Why does this matter? Because when the 19th-century railway bubble burst, we were left with railways. When the early-electrification bubble burst, we were left with the grid. And when the dot-com bubble burst, we were left with a lot of valuable infrastructure whose cost was sunk, in particular dark fibre. The AI bubble? Not so much; What with GPU burnout and power charges, the infrastructure is going to be expensive to keep running, not something that new classes of application can pick up and use on the cheap.
Which suggests that the post-bubble hangover will have few bright spots.
This is a set of purely financial issues but I think they’re at the center of the story.
It’s like this. The Big-Tech giants are insanely profitable but they don’t have enough money lying around to build the hundreds of billions of dollars worth of data centers the AI prophets say we’re going to need. Which shouldn’t be a problem; investors would line up to lend them as much as they want, because they’re pretty sure they’re going to get it back, plus interest.
But apparently they don’t want to borrow the money and have the debts on their balance sheet. So they’re setting up “Special Purpose Vehicles”, synthetic companies that are going to build and own the data centers; the Big Techs promise to pay to use them, whether or not genAI pans out and whether or not the data centers become operational. Somehow, this doesn’t count as “debt”.
The financial voodoo runs deep here. I recommend Matt Levine’s Coffee pod financing and the Financial Times’ A closer look at the record-smashing ‘Hyperion’ corporate bond sale. Levine’s explanation has less jargon and is hilarious; the FT is more technical but still likely to provoke horrified eye-rolls.
If you think there’s a distinct odor of 2008 around all this, you’d be right.
If the genAI fanpholks are right, all the debt-only-don’t-call-it-that will be covered by profits and everyone can sleep sound. Only it won’t. Thus, either the debts will apply a meat-axe to Big Tech profits, or (like 2008) somehow they won’t be paid back. If whoever’s going to bite the dust is “too big to fail”, the money has to come from… somewhere? Taxpayers? Pension funds? Insurance companies?
I think I’ve set that piece up enough now. It points out a few other issues that I think people should care about. I have one criticism: They argue that genAI won’t produce sufficient revenue from consumers to pay back the current investment frenzy. I mean, they’re right, it won’t, but that’s not what the investors are buying. They’re buying the promise, not of more revenue, but of higher profits that happen when tens of millions of knowledge workers are replaced by (presumably-cheaper) genAI.
I wonder who, after the loss of those tens of millions of high-paid jobs, are going to be the consumers who’ll buy the goods that’ll drive the profits that’ll pay back the investors. But that problem is kind of intrinsic to Late-stage Capitalism.
Anyhow, there will be a crash and a hangover. I think the people telling us that genAI is the future and we must pay it fealty richly deserve their impending financial wipe-out. But still, I hope the hangover is less terrible than I think it will be.