news
Programming Leftovers
-
Explain Extended ☛ Happy New Year: Lisp interpreter in SQL
This year, I'll be implementing a Lisp interpreter in SQL.
Now, what's Lisp, and why would I want to do that? Well, let me tell you a little story about that.
-
Amit Patel ☛ What I did in 2025
The main theme for this year was text. I wanted to be very broad in applying this theme: interpreters/compilers, procedural generation, rendering, language models, text editors, search engines, and anything else related to text. Last year I bought and started reading munificent’s excellent book Crafting Interpreters, but it wasn’t until this year that I spent a lot of time on it. It creates a new language, Lox, and then teaches you how to write an interpreter and compiler for it.
-
Daniel Lemire ☛ By how much does your memory allocator overallocate?
How much virtual memory does the following C++ expression allocate on the heap?
- new char[4096]
The answer is at least 4 kibibytes but surely more.
-
NSHipster ☛ Replay
The year is 2025. You’re writing tests for networking code in your Swift app.
You could hit the live API, but then your tests are slow, flaky, and fail whenever that third-party service has a bad day. You could stub URLSession, but then you’re maintaining two implementations of your networking layer. You could maintain JSON fixtures by hand, but there’s no way to capture real responses automatically, so your fixtures go stale without anyone noticing.
There’s a better approach: Record real HTTP traffic once, then replay it instantly for every subsequent test run. This pattern has been battle-tested for over fifteen years in other languages.
Replay brings it to Swift.
-
Loup Vaillant ☛ A SOLID Load of Bull
“SOLID” is an acronym devised by the famous advocate Robert C. Martin, to popularise what is now known as the SOLID principles. There are five of them: one good, one obsolete, and three invented by Martin himself.
Robert Martin is not your average Joe. I’ve watched him, he’s a very good speaker: articulate, driven, and entertaining. I’ve read his prose, he knows his rhetoric, how to deflect criticism, and how to play with the audience. I’ve seen his code, or at least the samples he carefully selected to be educational material, and holly crap that’s bad!
Not to beat on the Clean Code dead horse, but the code examples alone should have been enough to make any competent programmer sceptical of anything Martin has to say about programming. Unfortunately that hasn’t stopped his ideas from getting traction, and I’m getting sick of repeating myself about SOLID on programming forums.
So let’s do this once and for all.
-
Igor Roztropiński ☛ Modular Monolith and Microservices: Data ownership, boundaries, consistency and synchronization
As we already know, modularity matters more than whether we have one or many deployment units - single monolith or multiple services. The principles used to decide how many modules a system should have, and what exactly they are, should be based on the functionalities the system provides and the responsibilities it carries. Module design should have little or nothing to do with whether we would like to have one, two, three or ten separate services (deployment units). Systems should be divided into logical, functional modules that are as independent as possible; in an ideal world, every module would not know anything about other modules and contain everything required to provide its functionality and fulfill its responsibilities.
Today, we will not focus on the principles and heuristics by which to decide on the exact module structure. We will not reiterate well-known facts: microservices are not a cure for bad design (architecture) and are rarely needed for performance reasons; they mostly serve as an organizational tool, allowing many teams to work in parallel more easily. It is also debatable whether completely separate units of deployment (processes) are required to achieve this; I will address it in a future post/article (added 2025-11-28).
Instead, let's talk about the Data - its ownership, boundaries, consistency and synchronization.
-
Charlotte Ausel ☛ Simple Bidirectional Type Inference
The implementation was pretty straight-forward because we did the difficult part (figuring out which direction the arrows should be pointing) before we went to write some code. An advantage we have over the Hindley-Milner inference algorithm is that we can give a more specific error than simply 'failed to unify types A and B'.
One of the commonly cited disadvantages of bidirectional type inference is that we need to sometimes include type annotations in places where it seems 'obvious'. However: if we extend our langauge with let-bindings with type annotations and force everything at the top level to be a let-binding, then we should almost never need another type annotation in the body of the let bindings! This restriction isn't unrealistic for a language. For instance, both Rust and C require all top-level declarations to be functions, constants, or user-constructed types (as well as a few other constructs like macros). Even Haskell, which doesn't require top-level functions to have type signatures, advises to use them anyway. Thus, this wouldn't be too annoying for the user.
-
Perl / Raku
-
Arne Sommer ☛ Max Validate with Raku
Write a script to return the maximum number of words that appear in a single sentence.
-
-
Java/Golang
-
Trail of Bits ☛ Detect Go’s silent arithmetic bugs with go-panikint
Go’s arithmetic operations on standard integer types are silent by default, meaning overflows “wrap around” without panicking. This behavior has hidden an entire class of security vulnerabilities from fuzzing campaigns. Today we’re changing that by releasing go-panikint, a modified Go compiler that turns silent integer overflows into explicit panics. We used it to find a live integer overflow in the Cosmos SDK’s RPC pagination logic, showing how this approach eliminates a major blind spot for anyone fuzzing Go projects. (The issue in the Cosmos SDK has not been fixed, but a pull request has been created to mitigate it.)
-