Efficient frontiers, problem structure, and how to reframe your way to a free lunch.
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?
The efficient frontier
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.
By User:G2010a - Own work, Public Domain
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.
The efficient frontier... in engineering
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?
Probably not.
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.
But what if you decide you really are on the efficient frontier?
Surely, if you're on the efficient frontier (or the pareto front), then you must really have to choose, right?
Maybe.
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.
That was a fun history lesson. How do I actually put this to use?
When you're facing a problem and think you might need to make a tradeoff:
- Really test whether you're on the efficient frontier of the problem space (i.e. set of constraints imposed by system structure) you're facing. If you're not, think hard to find a way to formulate your solution to avoid any sacrifices.
- If you really are on the efficient frontier, spend some hammock time to think about how you might reframe the problem that your solving in such a way that the structure of the system (the relationships between its components) and the constraints that they imply push out the efficient frontier sufficiently far that you can easily achieve your goal without any sacrifices.
- When all else fails, make a sacrifice, write it down, and keep it in the back of your mind in hopes that some flash of insight one day allows you to reframe the problem.
Aren't you into statecharts? What does all of this have to do with that?
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
Follow @abrgBuilds and join the Simply Stated newsletter for more like this.
Top comments (0)