Every messy codebase hides deterministic cores you can defragment
Deterministic Core, Non-Deterministic Shell

Gary Bernhardt's Functional Core, Imperative Shell is a classic, but pure functional programming isn't always practical. The author argues we can relax the requirement from purely functional to merely deterministic, keeping the testability benefits while broadening applicability. Non-deterministic operations like RNGs, network calls, and clock reads belong in a shell. For legacy codebases, the author proposes 'Defragmentation of Determinism': find and group deterministic pieces, shrinking the hard-to-test surface area.
Every nasty mess of a codebase I've seen has one or more much nicer deterministic state machines locked inside. I promise you they are there, even if it's not obvious.
- kccqzy
I agree with the thrust of the article but I want to quibble with one thing: the article says “calling RNGs that aren't seeded” doesn’t count as deterministic behavior, but randomized algorithms often have simpler implementations and better asymptotics than non-randomized algorithms while having statistical guarantees (“almost surely”) on their properties. Two of my favorite examples: (1) a randomized quicksort where choosing the pivot randomly in each iteration is simpler and better than deterministic methods of choosing the pivot; (2) a randomized treap gives you a balanced binary search tree with far simpler implementation than say a red black tree. And that’s besides the more utilitarian security benefit of using randomness inside hash functions to protect against HashDoS attacks.
So I’d implore the author to delete this restriction. Even when randomized algorithms produce different outputs (the treap giving you differently shaped trees with the same sequence of inserts) these outputs have properties that can be checked statistically.
- Retr0id
I've been pondering something I call "slop core, artisanal shell", as a way of keeping vibecoding under control. Slop core might sound like the thing you want to avoid, but as long as it's purely-functional (or perhaps, merely deterministic) it should be robustly testable. The "artisanal shell" keeps the thing human-understandable and human-modifiable, as long as you put some thought into the API boundaries.
- consuming2
This split is familiar from Temporal.io: workflows are deterministic while activities are idempotent.