Michał Sapka's website

On Simple Software

As I’ve stated before, I’m not much of a gamer. Therefore, till recently, I had yet to learn who Jonathan Blow was. In short: he is an indie game developer responsible for Braid and The Witness - games I’ve meant to play for a long time but have yet to do it. He is also quite prolific at the interwebs and game development conferences. But what is most important is that he is a man of strong opinions, and I always had a hard-on for people having actual, individual thoughts. A rare breed, unfortunately.

The one talk of his that made the biggest impression on me was Preventing the Collapse of Civilization1, primarily because if inlines with what I’ve been feeling recently. The video is worth the time, but to make it brief: Blow states that their knowledge is lost when civilizations fall. And then he comes to the notion that we, software developers, suck because we don’t know how CPU works. It makes a lot more sense when he tells it, I promise!

But it all boils down to one thing: the simplicity of software. I am a web developer. And I know one thing most of us are proud of: we make simple software in a simple manner. But are we?

We write high-level code which abstracts levels upon levels of indirection. Take me, for example. When I write software at my job, I do it in Ruby on Rails. The code is then run by a Ruby virtual machine. The virtual machine converts my code to machine code during runtime. The machine code runs on Docker. Docker runs on a virtual server. The virtual server abstracts the real server somewhere in America. When my code wants to persist data, it talks with Amazon Aurora. Aurora is an abstraction of MySQL, running on a virtual machine, but we don’t care because we get charts on a website. We don’t manage the Aurora. Instead, we do it by changing Terraform code. Terraform is then read by Atlantis, and the changes are magically applied (or not - it seems like it’s random if it will succeed).

This, for sure, sounds complex and requires multiple people to understand what is going on, far from simplicity. And it makes everything much slower. But, we don’t perceive it because: The hardware is crazy fast now. This is one of the things Blow mentions: software is riding on hardware progress. We allowed ourselves to write slow software because it runs fast. All software nowadays is slow, so we are used to it. Seriously, look at how fast System Preferences on macOS ran ten years ago and how slow it is now.

But there is simplicity there: the delivery of software. The browser runs most software while most games are sold through Steam (on consoles, on their respective download-only stores). No longer do we need to maintain an inventory of actual physical discs. The trick here, however, is that we no longer need to write good software. We expect to ship bugs, as the cost of issuing a fix to all clients is close to zero. But how can we not ship bugs when the codebases we write are so vast? Dozens (if you are lucky; otherwise, hundreds) of separate programs run complex and intertwined business logic. No one can have a complete understanding of the design. That’s why big tech companies employ dozen of thousands of engineers. There is so much going on at any moment; there is a need for people to know precisely one piece of the puzzle. And our solution is lackluster automatic tests and a lack of documentation.

The way I see it: we write incredibly complex systems in a highly complex way that runs on extremely complicated infrastructure. Every solution to this problem just adds another level of complexity (cough Kubernetes cough), and we fool ourselves into thinking that is the way it was always meant. The worst part: it does not serve the user, as he is getting buggy software that is boring (design trends are the same as architectural trends - everyone does the same). All in the name of the business people.

Sustainability be damned, the third phase of software evolution is in full extent upon us, but it may be coming to an end. However, this is a subject for another rant.