Why is software so hard?
We begin with the premise that building software is hard to do. If you do not agree with the premise, I start doubting that you have built software before. That does not mean that I am not open to being surprised; after all I consider myself just a middling software builder, surpassed by droves of Jon Gjengset-level principal and staff engineers and technical fellows.
I have been programming for a while: I am approximately the age of the C language, and I was an early starter. My heart was captured by 1Mhz and 64kB of RAM. Within days of transcribing my first BASIC program, I started asking myself the question: “What is the best way to ‘arrange’ this?”. I guess I have never stopped.
So. Why is hardware so hard?
Software is intrinsically complex To begin with, software has some very unique “properties”. If we allow ourselves to make a comparison between software engineering and other engineering disciplines, we can establish a bit of a paradigm between software and the “substances” involved in other engineering disciplines: electrons, chemical reactions, structures, dirt and concrete, etc. In that comparison, which we will be exploring further, software comes out as unique in all the aspects we care to look into. In particular, software lends itself to giving rise to astounding degrees of complexity, to the extent that the number one directive when dealing with software is to curtail, corral, ameliorate, and minimize that complexity.
Building software is a human activity The other aspect of software difficulty stems from, as John Cormack put it, that building software is ultimately a social science, as it is an endeavor that involves teams, communities, and stakeholders. The goal of software builders is ultimately to build things of value, value being a human judgement[1]. More pointedly, it requires the interaction between experts at software, and non-experts. In my internal, secret vocabulary I call non-experts “civilians”, and sometimes “normies”. It requires the patience to engage SMEs in conversation, the humility to dig down and ask lots of questions. It requires engaging with people who do not know how to make the sausage, but often will try to tell you how to do so. It is humbling, and sometimes ponderous.
It is a marathon, not a sprint Software is not just complex, but it behaves in weird ways we are not used to. If you have ever had the misfortune to hear my “software as a substance” moments, you would have heard things like “it is emergent”, “information wants to copy itself”, “exponential permutations”, etc. I may have then bludgeoned you with phrases like “software estimates are wrong”, “engineering managers are wrong”, and my favorite, which I’ve stolen from some rando at IBM: “… then it is just a matter of programming.”
One of the weird ways about software, is that it is not a conservative field. In a conservative field, how you get from point A to point B does not matter. If you are climbing mount Everest, the physics say you can walk up the mountain side, or take a huge jump to the top, and the work done is the same. There is some sense that sometimes you are working with the field (gravity in this case), and sometimes against it, so a lot of the wandering evens out. Even weirder, it is not linear.
Imagine you have two tasks: add a feature, and clean up code. It turns out it matters greatly the order in which you do so (answer: clean up first), and you end up putting a lot more effort if you do it the wrong way. On top of that, software is long lived, so all that work becomes energy, the area under the effort curve. When was the last time a manager (not at a utility company) told you energy is money?
We are tasked, KPI’d, and rewarded for delivering a long stream of features, but that is not The Goal. Our mandate, revealed by St. McKinsey, is to maximize long term investor value. This is not achieved, in software, through features alone, but through a constant attention to code quality, suppleness (which is quality), readability (which is quality), testability (which is quality), etc.
It is a long term game in which, ironically, by paying attention to non-functional requirements first, we achieve The Goal.
Look at the software engineer in the cubicle next to yours. They are either delivering features and not giving a damn about the mess they are leaving behind, or they are scrambling like crazy cleaning up the campsite while delivering your precious, probably meaningless charts. And you are probably shafting the latter in your anonymous 360 evaluations, while praising the former.
The conclusion, in which I fumble for positivism The thing is, there are very good, very reasonable, very humane reasons why people are generally terrible at software[2]. Those reasons all amount to one thing: lack of awareness or willingness to understand the nature of software. Thus, one of my aims (at work, with colleagues over beer, at the dentists, etc.) is to establish a sense of virtue, not in the literal Roman sense of “manliness”, but in the sense of “that to which one should aspire to be.”
Fortunately, there have been plenty of people in the past that took the time to suss out a whole compendium of general categories of virtue (though sadly we have generally ignored them, as a species). My job becomes simply to repurpose and retarget some of the work of the ancients, and apply it to the business of software.
The good news is that they have done a good job, and you are familiar with the terms they threw around. They spoke of duty, discipline, charity, etc., it would be easy to stop thinking too hard and just sprinkle the goodness, like Oprah after reading the Nicomachean Ethics, and say our duty is to be disciplined in our approach to the work of software, and be advocates for the whole of the business, and educate our internal customers. I could even reach outside the proper garden of virtues, and throw things like in team-orientated, client-centric, or disruption-enabling. Those will pass as legitimate virtues to most crowds.
But, the language of Averroes and Kant is dated, and insufficient for the task at hand, and the moral imperatives around technology have their own urgency, because technology has become the most pervasive force in the world, and one of the few sources of hope we have left. And as we make progress as a species, we have slowly begun to understand how truly central and powerful computation is to our existence.
And that existence demands that software engineers become beacons of technological bad-assery, constantly driven to perfect our knowledge and our skills. It demands that our managers and political leaders refocus their mindsets to be humanist, humane, and stewards of their fellow humans. It demands of us to become better, smarter, more knowledgeable, more charitable, and more understanding.
I want engineers to be bold and fearless, and I want managers to be enlightened. I want both to feel inconvenienced by the fact that, after all, we are just human.
And somewhere downstream from that, at a much simpler scale, we need to trust software people to have the room they need to create healthy, long term, quality software. And software people need to earn and keep that trust.
And to conclude, the required self promotion If you enjoyed reading this, and you are not a masochist, you might want to wonder to my budding blog. There I have a bit more freedom to put stuff down and get into different things. This whole thing is terrifying, so thanks for your patience.
Which, if you think about it, is why programmers cannot be replaced completely by AI. By now you may have thought: “Heyyy, what about the Netflixes, Amazons, Googles out there!”, and you’d be right. There are centers of software excellence out there (IMO, most notably, Jetbrains). Outside their shining cities, though, in the wilds, the 99% writhe.