Reading code instead of writing code: The underestimated senior discipline

As early as 2000, Joel Spolsky warned against reading code rather than rewriting it. With LLMs, his diagnosis becomes a pressing question for every team.

listen Print view
Scene in a color-poor office: 2 men and 1 woman, all with darker complexions, are gathered around a desk with a screen; the woman (center) points to the screen.

(Image: Gorodenkoff/Shutterstock.com)

15 min. read
By
  • Golo Roden
Contents

In April 2000, Stack Overflow founder Joel Spolsky published an essay titled “Things You Should Never Do, Part I”. The occasion was Netscape's decision to rewrite the code of its then-browser from scratch instead of further developing the existing one.

Golo Roden english
Golo Roden

Golo Roden is the founder and CTO of the native web GmbH. He works on the design and development of web and cloud applications and APIs, with a focus on event-driven and service-based distributed architectures. His guiding principle is that software development is not an end in itself, but must always follow an underlying technical expertise.

Spolsky's thesis: This decision was the worst strategic mistake a software company could make. It was based on a fundamental misunderstanding of what programming work actually is. Programmers prefer to rewrite because reading foreign code is tedious and writing feels productive. But this impression is deceptive. The temptation to start over is one of the most expensive temptations in the industry.

More than 25 years later, this text has lost none of its relevance. On the contrary. With the advent of Large Language Models (LLM), the asymmetry between writing and reading has shifted to such an extent that the question becomes acute whether we are systematically underestimating the true senior discipline of software development. Typing is not what will keep teams breathless in the coming years. Reading is. In this article, I want to show why this is the case, where the asymmetry comes from, how it is exacerbated by generative AI, and how a casual accompanying skill must become an independent discipline.

When writing, you have everything in your head at once: the requirement, the data model, the planned architecture, the part you are currently working on, the assumptions you are making, the trade-offs you are entering into. This overall mental view makes writing fast. It is also what is missing when reading.

If you look at the same code again three weeks later without bringing the context, you have to reconstruct this overall view. Variable names provide clues, tests say more, a pull request comment provides the technical reason in the best case, a commit message with luck the last justification. The actual intention, the thought model, the discarded alternatives, all of that is lost. Reconstruction costs time and concentration, and both are pricier than writing.

Videos by heise

Spolsky's anecdote is so vivid because it shows this asymmetry at the organizational level. At Netscape, they were faced with an old codebase that no one wanted to decipher anymore. The temptation to simply rewrite the whole thing was strong. The result is known: three years of stagnation, a lost browser market, a company declining. The seemingly easier path was the most expensive.

At the individual level, the same pattern repeats daily. It appears in Stack Overflow answers that suggest an alternative instead of answering the question. It appears in colleagues who suggest refactorings without really understanding the existing code. Furthermore, it appears in the temptation to replace a module rather than improve it. Reading is and remains inconvenient.

A modern LLM generates several hundred lines of code in the time it takes a person to skim those lines once. Generating has become cheap. Tokens are cheap, waiting times are short, and the mental model for the task has shrunk to formulating a prompt. The effort on the writing side has effectively collapsed.

On the reading side, nothing has changed. Understanding still costs what it always has: focused attention, time, patience. The human processing speed for code is roughly a few lines per minute, significantly less depending on complexity. This magnitude cannot be accelerated by tools because it depends on human cognition itself.

The result is a grotesque shift. Where a day's work used to produce about a hundred lines of code that a reviewer could go through in half an hour, an hour of prompt work can now generate thousands of lines. The amount to be understood grows dramatically, while the speed of understanding remains constant. What used to be a bottleneck in writing now becomes a bottleneck in understanding.

This shift is ignored in many discussions. Productivity on the generation side is celebrated, while the balance on the reading side is silenced. What is not read is not understood. What is not understood is not reliably operated. The debt merely shifts to the future; it does not disappear.

This becomes visible at the latest where code review processes, designed for the speed of the pre-LLM era, are suddenly confronted with pull requests whose scope a human reviewer could not grasp in a whole day. The reaction is usually not a more profound engagement but a shortened thumbs-up. This shifts code review from a substantive to a ceremonial step, and it is precisely in this shift that the problems arise that become expensive later.

An ambitious school of thought propagates that dealing with code will become superfluous: with enough skills, harness engineering, and a precise Markdown specification, the work can be completely shifted to the spec level. The generated code is an implementation issue that no one needs to look at anymore. This idea will run headfirst into a wall.

Anyone who only generates code without reading it is faced with foreign code from the outset. Reviewing is not possible, finding errors is not possible; both require understanding. With each further generation, the codebase grows faster than it can be deciphered. The gap between “existing” and “understood” opens up at breathtaking speed, and with it the number of places where you will later have to ask what is actually happening here.

The only remaining instance that can still explain, check, or repair this code is the AI itself. Thus, one ironically becomes dependent on the very system that caused the situation. A tool becomes a dependency; acceleration becomes a trap. Anyone who does not build up their own understanding competence is left with only an external one and no longer decides on this external competence themselves.

This pattern is not new; only its speed is new. A team no longer possesses an inaccessible codebase. In the classic case, inaccessibility occurred over years, through personnel changes and insufficient documentation. In the AI-assisted case, this can happen within a few months because the generation speed hopelessly exceeds the absorption speed.

The typical trigger is not spectacular. A bug appears in production; no one in the team understands the affected code, so they ask the AI. The AI provides an explanation and a fix, both plausible, both unchecked. In the best case, it's correct. In the less favorable case, you build new debt on old debt and only notice it when the next bug arises precisely in this layer. Repair becomes overpainting.

What initially seems like a liberation is therefore a shift of the burden. Instead of writing yourself, you formulate prompts. Instead of understanding yourself, you ask the AI. Both seem productive. Both erode sovereignty over your codebase.

Don't miss any news – follow us on Facebook, LinkedIn or Mastodon.

This article was originally published in German. It was translated with technical assistance and editorially reviewed before publication.