Skip to content
The AI-First Web

The Friction Is the Feature: What We Lose When Code Writes Itself

Implementation isn't the boring transcription of a finished idea. It's the interrogation that turns vague intention into precise requirements. Remove it, and you ship the contradictions.

K
Kannan SP
· 6 min read
Share on X LinkedIn
The Friction Is the Feature: What We Lose When Code Writes Itself

Every era of computing has been a campaign against distance — the distance between what a human wants and what a machine does. Assembly shortened it. Compilers shortened it dramatically. High-level languages, frameworks, and IDEs kept shrinking it. Today, AI coding assistants let us describe software in plain English and watch it materialize — "vibe coding," as the current fashion calls it. And research on brain-computer interfaces is starting to sketch the campaign's logical terminus: skip the keyboard, skip the language, and translate <em>thought itself</em> into running code.

The pieces of that endpoint are no longer science fiction. Implanted interfaces have decoded attempted handwriting at useful speeds and reconstructed speech from the brain signals of paralyzed patients. The realistic near-term architecture isn't pure mind-to-code — non-invasive headsets remain noisy and low-bandwidth — but a hybrid: the brain supplies coarse, high-level intent ("loop over these, roughly this function shape"), and a code-trained language model expands it into detailed syntax. Thought in, software out.

I find this trajectory technically thrilling and philosophically alarming in equal measure — and the alarm has nothing to do with Luddism. It comes from a suspicion that this final abstraction misunderstands what our discipline actually <em>is</em>.

The old distinction that settles the argument

Four decades ago, Fred Brooks gave software engineering its most durable distinction: the <em>essential</em> complexity of a problem versus the <em>accidental</em> complexity of implementing a solution. The essence is the conceptual structure — what the software must actually do, under which constraints, for whom. The accidents are the incidentals of expressing that structure in a particular language on particular hardware. Brooks's point, which four decades of tooling progress has only confirmed, is that our tools keep getting better at destroying accidental complexity — and the essential complexity doesn't budge.

Every abstraction leap in computing history has been a victory over accidents. The seduction of thought-to-code is that it markets itself the same way: the ultimate removal of accidental complexity. But look closely at what it actually removes. When a tool translates a <em>vague thought</em> directly into a <em>finished artifact</em>, it hasn't eliminated the accidents. It has skipped the stage where the essence gets discovered.

Nobody knows what they want until they try to build it

Here's the inconvenient truth every working engineer knows and every frictionless-creation pitch ignores: <strong>the requirements are not in your head.</strong> Not fully, not precisely, not consistently. What's in your head is a sketch — plausible, appealing, and riddled with contradictions you cannot see yet.

The way those contradictions surface is <em>the act of building</em>. You start implementing the sketch, and reality starts asking questions. What happens when this input is empty? These two requirements — did you notice they can't both be true? This "simple" feature — did you realize it implies distributed state? Implementation is not the boring transcription of a finished idea. It is the interrogation that turns a vague intention into a precise one. The messy, detailed work is the crucible; vague intent goes in, real requirements come out.

This is why I've started saying that the friction is the feature. The resistance you feel when forcing an idea through a compiler, a type system, a code review — that resistance is <em>information</em>. It's the idea's inconsistencies pushing back. A pipeline that translates intent to artifact without resistance doesn't make the inconsistencies disappear. It ships them.

The dial, not the switch

It clarifies things to see the current tooling landscape as one continuum. Manual coding: maximum friction, maximum forced understanding. Autocomplete: a bit less of both — studies already note "suggestion bias" and shallower API knowledge. AI pair-programming: faster still, with hallucinated or subtly defective code as the new tax. Vibe coding: thin mental models and brittle architectures accumulating as maintenance debt. Neural coding: the far end, where the human contributes intent and comprehension of the artifact approaches zero.

Notice what moves along that dial. Not just speed — <em>where the cognitive work lives</em>. At the left, the work is explicit reasoning about a system you're constructing. At the right, it becomes oversight of an opaque machine's output. The work doesn't vanish; it degrades — from creation to auditing, and eventually to hoping.

And there's a version of this future that doesn't scare me, because we already know what disciplined abstraction looks like. Model-based engineering generates code deterministically from <em>validated models</em> — speed gained while every artifact stays traceable back through design and requirement to intent. The credible pipeline isn't thought → code. It's thought → <em>formalized</em> intent (assumptions, invariants, constraints) → checked models → code — with humans able to reason, negotiate, and audit at every arrow. The difference between the two pipelines is the difference between abstraction and amputation. One compresses the path from intent to artifact while keeping every link inspectable. The other severs the links and calls it progress.

Software, meanwhile, isn't even written by individuals anymore — it's negotiated among stakeholders with conflicting goals, which is why "intent" worth building from has to be a <em>shared, checkable artifact</em>, not a private mental state. A brain scan of one developer, however high-fidelity, is an answer to the wrong question.

The judgment we'll actually need

None of this argues against better tools; I use AI assistance daily and gladly. It argues for knowing which half of the work the tools are actually doing. They accelerate expression. They do not — cannot — do the discovery that happens when expression meets resistance. And a system's ultimate quality never comes from the intent behind it; it comes from the care with which that intent was tested, challenged, and forged into something precise.

So before adopting each new rung of the abstraction ladder, the question I ask isn't "how much faster is this?" It's: <strong>where did the friction go?</strong> If it moved somewhere productive — into checked models, into explicit constraints, into tests that interrogate the idea — climb. If it simply disappeared, be suspicious. In engineering, friction that disappears without a trace hasn't been eliminated. It's been deferred — with interest, payable at 3 A.M., in production.

Share this insight