I heard this the other day:
In theory, this should work.
Me: 😱
No, :face_screaming_in_fear:
isn’t
quite right, this isn’t fear. Perhaps it’s anguish. Or shame. Or
sorrow.
To me, “In theory, this should work” denigrates and destroys the notion of theory. “theory” as a notion of practice that might not work.
We have other words to denote uncertainty!
It’s perfectly fine, very common and super useful to make the things you don’t understand explicit. Saying “I don’t know how SQLite works” names the problem, and makes it easier to understand SQLite later. You have now turned an unknown unknown into a known unknown.
So if theory is not “things that don’t work in practice”, what is theory?
I propose the following:
A theory has explanatory power. All other things being equal, a theory that explains better than a different theory is better.
A theory has reach. A theory explains things within some domain. That is the reach of the theory. All other things being equal, a theory with larger reach than a different theory is better.
A good theory is hard to vary. If you can change arbitrary parts of your theory, and the theory still holds, the theory is too big. Something can probably be removed. And removing that thing will make the theory better.
Good practice produces a result. If that result is what you need, the practice works.
A practice is better than a different practice if it produces better results.
Where do you want to go? If you don’t know, you probably won’t end up there. If you don’t know where you want to end up, your goals aren’t good enough. If you don’t know why you did the things you did the last two months, your goals aren’t good enough.
If the things you do don’t get you where you want to go, you have bad practice.
Is what you’re doing clear? Or is everything hard to describe?
Do you know what you did for the last two months? Or did you get where you wanted, but you have no idea what you did?
The act of building theory clears things up. Introducing a good theory that is appropriate for the problem at hand makes the problem easier to understand.
Sometimes you can even apply known theory and known terminology, you don’t always have to invent everything from first principles.
Back to the source of our frustration:
In theory, this should work.
So, which theory???
Theories make things clear by making things explicit. If you do want to talk about theory, at least let others know which theory you are referring to. Because there are infinitely many to pick from, and possibly not obvious to others which one you meant.
Or, you can choose to not talk about theory! That is perfectly fine. “My goal is to display the current time in the CET timezone. Can you help me achive that?” No theory required to ask that question!
Cities need water. From what we know about Rome’s population in 200BC we could estimate a required water supply. Aqueducts were built, and still stand. In the middle ages, engineers understood how effective arch shapes for building build cathedrals. Today, we have continuum mechanics, a theory that explains arches, and more. Continuum mechanics lets us simulate the behavior of our arch, and observe the structural response before we build our arch:
Software engineering is a young field. We don’t yet agree on our shared foundation. Marty Cagan style product management gives one approach to goals, continuous delivery gives approach to practice, and functional programming gives one approach to theory. But this is seen as one approach. We haven’t built a shared foundation, yet.
Perhaps the next 50 years of software engineering will change that? I’m eager to find out.
—Teodor 2024-06-17
PS. My notion for theory is stolen from David Deutsch. I whole-heartedly recommend reading his book The Beginning of Infinity. This guy is great at explaining things, knows quantum physics in depth and knows epistemology in depth. In other words, he’s quite good at theory, both in theory (epistemology) and in practice (how quantum physics helps us understand reality). He’s a person worth learning from.
PPS. Design documents and tests can be the foundation for your theory for your codebase. They can help explain. But if you start out by assuming they are useless, they will become useless. If you intend to explain the codebase in the README and with tests, you need to use the README and use the tests in practice. Re-read the README in a moment of uncertainty. Does something need to be added? Run and read the tests to understand how things are meant to work. Then add tests for the new code you’re adding too.