We always talk about tradeoffs. Strike up a conversation with most engineers about almost any problem they've worked on and you're likely to hear a lot about how they had to consider and choose from among various tradeoffs.
Living in a tradeoff-rich world, many of us start to assume that literally everything requires tradeoffs. Want better performance? Better sacrifice readability. Want quicker time to market? Get ready to give up reliability and correctness. Pareto improvements? Never!
...But does every improvement really require a sacrifice somewhere else?
Let's take a quick diversion into finance. Modern portfolio theory is based on the idea that every portfolio (basket of assets) has a volatility and expected return derived from the assets and their cross-correlations. The space of possible volatility/return pairs is constrained by the available assets and, in particular, their inter-relationships (correlations). That is, if you plot the volatility/return of all possible portfolios composed of some set of assets, you'll find a boundary you can't cross. At that boundary, called the efficient frontier, you can pick your tradeoff between risk and return but you can never construct a portfolio with a higher return and equivalent risk or lower risk and equivalent return to one on the efficient frontier. However, if you have a portfolio inside the efficient frontier, you can do strictly better--increase your return and keep the same level of volatility or reduce your volatility and keep your same return--by moving up or over to a point on the efficient frontier.
As an example, if your portfolio consists entirely of umbrella maker stock, you could probably achieve higher returns with lower risk by adding a few shares of an ice cream manufacturer. However, there is no combination of umbrella and ice cream stock that will get you 50% returns with 10% volatility--that is beyond the efficient frontier.
So, how is this related to software and engineering?
First of all, we need to swap the x-axis from the above picture. In engineering, our axes represent limited quantities and we'll assume more is better but we tend to have a maximum achievable quantity on each axis. (Technically, we're now talking about Pareto Frontiers). For the rest of this article, imagine x and y axes labeled with quantities like: performance, readability, agility, ease of maintenance, scalability, engineering time, number of engineers, etc. such that more is "better."
Anyway, once you're on the efficient frontier, everything really is just tradeoffs. There is no free lunch. You must give up something to get more of something else.
But if you're inside the efficient frontier, you actually can do strictly better. You don't need to give up any x to get more y. You have a menu of tradeoff-free improvements to choose from.
So, is everything really just a matter of picking your poison and making the right sacrifices to hit a reasonable set of tradeoffs?
There is plenty of knowledge sharing and competition driving us all to find and adopt better and better ways to structure our systems but how sure are you that you're actually on the efficient frontier, that you've reached the best of all possible configurations such that nothing can possibly be improved without giving up something in return? Based on what we've seen in industry, that's just not very likely.
At the very least, whenever you're discussing a tradeoff you think you have to make, spend some time to really convince yourself that you're already on the efficient frontier, living in one of the best of all possible worlds.
Surely, if you're on the efficient frontier (or the pareto front), then you must really have to choose, right?
But remember, the efficient frontier was determined by the interrelationships between the components of our system or, as I like to call it, by the structure of the system. In the portfolio theory case, the structure was governed by the correlations between assets. In our engineering case, the structure of the system is governed by the constraints of our problem space.
It's tough as a market participant to change asset correlations (and I'm fairly certain that the SEC looks unkindly on those who attempt it).
It's also tough but eminently possible as an engineer to change your conception of your problem space.
React did just that. Prior to React, we were all solving the problem of mutating the DOM in response to events and--wow!--that problem has a shallow efficient frontier. React reframed the problem to one of updating abstract state in response to events and generating a DOM based on that state and immediately pushed out the frontier of the possible.
The key insight here is that the same business problems can be approached by solving any one of many possible technical problems. The mapping from business problem to technical problem is many-to-many. But the choice of technical problem determines the structure of the technical domain, which determines the efficient frontier of what's possible.
Pushing out the efficient frontier by uncovering a new problem structure that subsumes a significant set of use cases of the current best alternative is no mean feat. These are the events in the history of programming we still talk about decades later and look back on the before times with astonishment: "they used to program like that?!?!" Time sharing, structured programming, OOP, functional programming, map/reduce, Docker, and React are all examples of structural reframings that changed the constraints engineers had to deal with in solving business problems. The big ones change the world. Plenty of small ones have changed industries, markets, and companies. Uncovering new structures, new relationships between components, is a worthwhile goal.
When you're facing a problem and think you might need to make a tradeoff:
At Simply Stated, we believe that statecharts represent a key reframing of the problem space of building apps. Whether you're looking at how product teams collaborate, how engineers implement solutions, how companies gain confidence that those solutions work, how customers learn to use them, or how those solutions can be safely adapted over time, we think statecharts and, more generally, declarative logic expand the set of achievable outcomes. We're tired of using (and, admittedly, building) software that doesn't work and takes hundreds of people too long to build. We think we can build better software faster with statecharts and declarative logic. That's why we want to contribute to the ecosystem of tooling needed to achieve mass adoption of this transformative reframing of the problem space facing engineers.
Since it cost a lot to win
And even more to lose
You and me bound to spend some time
Wondering what to choose
- The Deal, Grateful Dead