Cover image for  "When Software Gets Complicated"

"When Software Gets Complicated"

ben profile image Ben Halpern ・4 min read

Software is inherently complicated. There's a lot going on. Developers tend to be fascinated with complicated systems. Even though over-complication tends to make things harder, we have a way of embracing it. Some things need to be complicated, and sometimes we just expect things to be complicated so we do not fight it. It is the natural order for things to get more complicated, but there are compounding side effects of that tendency that must constantly be examined.

Our software can scale to infinity, but our brains cannot. This is why we need to build composable applications, develop clean APIs, and cover our code with automated tests. We create mental models in order to better understand and communicate what the hell is going on. We use metaphors to simplify and communicate, or at least we should. We tend to get excited about our own capability of wrestling with complicated problems and finding solutions. I can have a long conversation with another coder where we may each go on and on about how we have tackled impressively, but if we have not addressed these problems in a communicable manner, we are accruing weight that is going to be hard to shed if we ever need to. Our supposed solutions grow in complexity that outpaces our ability to communicate that complexity to others.

As projects grow, be they commercial applications or open source frameworks, or what have you, we solve more problems, but we create surface complexity that makes the entire mental model breakdown. The simplicity with which we were once able to communicate breaks down completely. To offer a concrete example of what I am trying to describe in my own development landscape, React, Facebook's popular JavaScript library, has had a turbulent time mitigating complexity. When it was first open-sourced, the idea had push back: the ideas of co-locating markup and logic was icky to many and people did not get it. Eventually, around React.js Conf 2015, the team was able to hit on the points that made it so damn exciting, the promise of harnessing data flow in a way that solved problems, reduced complexity and offered performance benefits. React Native was the cherry on top. "Learn once, write anywhere". It was a beautiful promise and people flocked. It is clear that React has been a big deal since that inflection point.

But since then, things got hairy. People ran into complexity problems trying to do a lot with the library, and while I think developers tend to find solutions, the new solutions were not as elegant and simple as the promises that got people there in the beginning. Structures built on top of React offered wonderful technical solutions, but were not there in terms of offering the kinds of mental models that made adoption so smooth in the first place. As much as Redux, Relay, GraphQL, et al, are wonderful technical solutions, they lack the grokability that human developers ideally need. I am not trying to stick my nose up at the solutions created by people that are smarter than I, but pragmatically I feel like their roles as open-source solutions. Perfect is the enemy of the good, but the same clarity of purpose that played so well for React is not quite there yet in the greater ecosystem. It may be that the problem is too intrinsically complicated to be any "simpler", but you could easily have said that about the core React API, and the team was able to sufficiently diffuse the intricacies and get people "thinking in React". The community still has a ton of momentum, but the complexity creep has outpaced the community's ability to provide models that break down the mental load for developers.

As an activity, be it software development, React development, or development within an organization, gets more popular, more and more users become power users, and because human communication abilities do not scale the way code does or the way the size of a community does, the tendency will be for those power users to take up a bigger and bigger chunk of the overall conversation. They are the 1% who will have the biggest influence on the decisions. They are also likely to have an outsized tolerance for complexity and are most likely to exist within an echo-chamber of folks who have the same tolerance. React is taking steps in the right direction with create-react-app, but this will be an ongoing struggle.

Complexity cannot be fought into submission. Every solution has some amount of "appropriate" levels of complication. It is also very much a matter of personal taste, which is a big reason why open source projects need not "win out" over others. But complexity absolutely must be checked, and checked often, because it is far easier to create complexity than to squash it.


Editor guide