The Software Iron Triangle
The "iron triangle" of project management is "Cheap, fast, good: choose two". This works on the assumption that quality is a metric while time and money are fungible constraints. We can exchange between time and money, and also lower our quality goals to require less of both. Then by LeMond's law1, if you aren't using much of your resources, you can afford to be more ambitious and put yourself in a place that does demand more from your resources.
It occurs to me that we can flip "quality" around into a constraint by saying is a "shoddiness" is a quantity we can spend to make the product worse. Then time, money, and shoddiness become our three budgets that all work against each other— we can pay shoddiness and time to save money, etc. The three resources are also conceptually independent: most other resources we can think of (favors, scope) fall clearly into one bucket.
That got me wondering what the software iron triangle would look like. Not the development of software, which falls under project management, but the software itself. Are there fundamental constraints that act as universal conflicting budgets? I'm pretty sure I know what two of them are, but the third I'm more uncertain about. They are performance, complexity, and (possibly?) correctness.
Performance also includes other resources like memory or power-use, but the dominant resource in this budget is wall time. Most problems are solveable by brute force; we don't do that because that's an unacceptable performance cost. Over time computers become faster and we get more of this budget to work with, which leads to adages like "developer time is more important than CPU time". But we don't have an infinite budget, and it's easy to waste too much of this resource if you're not paying to it as a constraint.
(Additionally, as computers get faster, there are more things that become feasible, so there's always a large problem space where your performance budget is the most critical. My new workstation can do constraint solving 5x faster than my old laptop, so even more complex problems become feasible, and those I'll need to optimize.)
Complexity is also a budget, in the cognitive overhead required to understand and modify the code. A useful proxy for this is size of the source code. The more lines of code you have, the more room you have to implement performance optimizations and robustness code, while the more lines someone has to read to understand it. It's not a 1-1 correlation, but it's useful enough to see how complexity can be a "budget".
As with time and money in the project management triangle, we can be more efficient with our spending of the complexity budget. Levels of abstraction let us scale the marginal complexity of a line of code more slowly, but this comes at the cost of performance.
"Correctness" is the one I'm least sure about. It feels like a good analog to "quality", but I don't know if it really counts as a budget. The way I see it, "correctness" can be considered a constraint in the form of "robustness". Consider a database form that fails to save if the user puts in emojis. You could tell the user "don't do that", in which case it's less robust, but simpler and (possibly) more performant. Or you could make it handle emojis at the cost of code complexity.
In the extreme, prioritizing correctness over everything else leads to Edge Case Poisioning.
Maybe the third constraint should be "features"? More features are more expensive and lead to more complex software to maintain them all. The reason I'm a little less confident in this is that it changes the scope of the software, too.
(I'm not very satisfied with this newsletter, will probably send another one later this week.)
-
"Ambition expands to fill the resources provided". After the cyclist Greg LeMond's quote "It never gets easier, you just get faster". ↩
If you're reading this on the web, you can subscribe here. Updates are once a week. My main website is here.
My new book, Logic for Programmers, is now in early access! Get it here.