I find there's a good way to not commit, slightly different from this article.<p>There's a non-committal way of designing software that I think we should all strive to follow. It's not things like "let's use an ORM so that we can swap the database later" or "let's write abstractions over everything so we can swap everything later". It's more that you're trying to keep the code as simple and static as possible, naively doing the exact business function, and rarely generalizing. There are a few practices I've picked up over the years for non-committal architecture of this kind (for example: doing more at "build" time, passing the functions what they need instead of what you have, keeping IO in shell layer, and a few more). The goal is not to end up with a codebase that has foretold all the possible futures, but that implements just what it needs to do now in the most straightforward way, such that it's easy to read, understand, and change. I think this kind of non-commitment is the ideal to strive for. The less committed you are in this way, the easier it remains the change the codebase as it evolves, the less shackled it is with over-engineered "solutions".<p>It's deceptively hard to do this in practice. Everybody wants to implement their over-engineered "system for doing a thing" layered on top of the programming language. Sometimes we forget that the programming language itself is a great tool for expressing business logic.