Musings on Software Complexity
I’ve spent 22 years in tech. And one thing anyone who’s been in the industry this long will tell you is that the degree of complexity involved in building software for a modern computer, from the bottom up, is truly, mind-blowingly, incomprehensibly, staggering.
Abstractions atop abstractions, dependencies upon dependencies at build and run time, archeological layers of backward compatibility and reasons-for-being, remnants of design trends that came and went, vestigial features never fully developed, unique and bespoke solutions and optimizations, workarounds for hardware, unexpected behaviors long fossilized into an unspoken part of the interface—and all under active development and maintenance by legions of humans, ever-changing.
It’s an awesome testimony to the ability of humans to tame (or at least safely ignore) complexity to a level that fits within working memory; to come up with abstractions that define a problem space which can then be wrangled by a small team.
But once in a while, you look behind the veil and see the billions of tiny gears meshing to create a working machine, and wonder how it all works. And yet, it mostly does. No one can comprehend the whole, yet somehow, everything comes together as a useful tool.
I’m not sure whether this is a reason to celebrate or mourn, but it is something marvelous to behold.