I’ve re-read A Philosophy of Software Design over the weekend to reframe how to approach software design in the age of AI tools. It is my favorite book on software design, and it feels like time to revisit some of the concepts again.
The third chapter got me reflecting:
Working Code Isn’t Enough
What stood out was the idea that tech debt is incremental. Hundreds of small tactical diffs turns into a ball of complexity over time. AI tools has made tactical programming much more attractive, because it raises the bar on velocity to deliver.
Management and cross-functional stakeholders love this:
“What took us a week now only takes a day!”
I did not realize the massive opportunity to do the opposite: hold the ship velocity steady (which should be fast), but force ourselves to ship it right and strategically. What used to take a week with corners cut, should still take a week with the help of AI, but without corners cut.
We used to make the fast, good, cheap trade-off triangle, but AI tools has somewhat blurred the lines, especially between fast and good. The recommendation Ousterhout gave was:
rather than implementing the first idea that comes to mind, try a couple of alternative designs and pick the cleanest one.
The key assumption was that experimentation takes time. But now we can perform these idea explorations in parallel with agents running on git worktree. We then evaluate which one feels the cleanest, and move those into the local branch to polish up.
I’ll challenge myself for the rest of June to embrace this principle, and see how far that gets me, at least until the next wave of AI improvements.