Code is a liability (not an asset)
Code is a liability (not an asset). Tech bosses don't understand this. They think AI is great because it produces 10,000 times more code than a programmer, but that just means it's producing 10,000 times more liabilities. AI is the asbestos we're shoveling into the walls of our high-tech society:
Code is a liability. Code's capabilities are assets. The goal of a tech shop is to have code whose capabilities generate more revenue than the costs associated with keeping that code running. For a long time, firms have nurtured a false belief that code costs less to run over time: after an initial shakedown period in which the bugs in the code are found and addressed, code ceases to need meaningful maintenance. After all, code is a machine without moving parts – it does not wear out; it doesn't even wear down.
This is the thesis of Paul Mason's 2015 book Postcapitalism, a book that has aged remarkably poorly (though not, perhaps, as poorly as Mason's own political credibility): code is not an infinitely reproducible machine that requires no labor inputs to operate. Rather, it is a brittle machine that requires increasingly heroic measures to keep it in good working order, and which eventually does "wear out" (in the sense of needing a top-to-bottom refactoring).
To understand why code is a liability, you have to understand the difference between "writing code" and "software engineering."
"Writing code" is an incredibly useful, fun, and engrossing pastime. It involves breaking down complex tasks into discrete steps that are so precisely described that a computer can reliably perform them, and optimising that performance by finding clever ways of minimizing the demands the code puts on the computer's resources, such as RAM and processor cycles.
Meanwhile, "software engineering" is a discipline that subsumes "writing code," but with a focus on the long-term operations of the system the code is part of. Software engineering concerns itself with the upstream processes that generate the data the system receives. It concerns itself with the downstream processes that the system emits processed information to. It concerns itself with the adjacent systems that are receiving data from the same upstream processes and/or emitting data to the same downstream processes the system is emitting to.
"Writing code" is about making code that runs well. "Software engineering" is about making code that fails well. It's about making code that is legible – whose functions can be understood by third parties who might be asked to maintain it, or might be asked to adapt the processes downstream, upstream or adjacent to the system to keep the system from breaking. It's about making code that can be adapted, for example, when the underlying computer architecture it runs on is retired and has to be replaced, either with a new kind of computer, or with an emulated version of the old computer:
Because that's the thing: any nontrivial code has to interact with the outside world, and the outside world isn't static, it's dynamic. The outside world busts through the assumptions made by software authors all the time and every time it does, the software needs to be fixed. Remember Y2K? That was a day when perfectly functional code, running on perfectly functional hardware, would stop functioning – not because the code changed, but because time marched on.