After Code Is Cheap
Six reasons cheap code won't mean abundant usable software
«No AI was used in writing this article, but it’s informed by the many discussions and articles I’ve read online.»
Code has become a lot cheaper to produce. But cheap code won’t mean an abundance of usable software. I propose six reasons why:
Coming up with novel ideas worth pursuing is hard. Ideas were supposed to be a dime a dozen, with execution being the hard part. Well, coming up with ideas that are both novel and useful has never been easy; that difficulty was merely and somewhat obscured by the labor cost of writing code. This is why, in an era of inexpensive coding agents we see mobile app stores flooded with clones of existing apps rather than truly new ones, and enterprises struggling to find novel and productive applications of AI.
Communicating our intent to a coding agent will always leave gaps. It is impossible to specify any sufficiently complex intent or behavior completely and unambiguously in natural language. Natural language is more expressive than code, but it carries ambiguities and gaps that are open to interpretation. Remember the popular maxim: ‘a sufficiently detailed spec is code.’ Just as with human coders, every gap in your specification is an opportunity for the model to insert its own interpretation.
Verifying that a program works as intended requires humans in the loop. There are two challenges that will need humans to address. First, having agents write tests from the specification does not solve the verification problem: a natural-language specification will always contain ambiguities and gaps, so any automated verification derived from it inherits those gaps, leaving a human to check the application’s behavior manually. Second, we often can’t know what a product should look like or how it should behave until we use it, so iterative development with humans in the loop is unavoidable in all but the simplest of cases.
Creating products with tasteful features and interfaces needs humans (for now!). Taste seems like an ineffable, hand-wavy concept, but to me taste in this context is the ability to step outside the default distribution in a way that is still right for the specific situation. The intrinsic human craving for novelty puts a premium on products that take novel approaches tailored to specific situations. Models draw from broadly similar training distributions, and even those trained on new examples stay within that distribution until the next major release. The result is an abundance of sameness: what we now pejoratively call ‘AI slop’. It doesn’t matter that the same output would have been considered high-quality just a few days ago; the sheer abundance of the sameness is what turns it into slop. Finally, taste is also about deciding what not to include (think of all the things Steve Jobs chose to leave out, against the ‘default distributions’ of his day).
Intra-organizational friction is unavoidable. We are social animals, and almost all our endeavors involve more than one person. Convincing others that this is the right product or feature to build out of many candidates will still be required. When a working prototype took two weeks, deciding which one to build needed alignment. Now that anyone can produce one in an afternoon, we are back to arguing over evidence of real user value or the strategic fit. And even once everyone agrees on one idea, the reviews and approvals from security, risk, legal, and compliance departments won’t go away.
Real-world friction is unavoidable too. Software has to operate in a complex world of regulation, geopolitics, competition, and the constraints of physical reality. Think of Uber, Waymo, or DoorDash. Regulatory approvals will continue to take time, and the rules in areas like data residency and privacy laws keep changing.
In conclusion, coding agents will make coding meaningfully faster, but we will see only a modest increase in the amount of software ultimately shipped to users.


