Thinking at the Speed of Code
updated
“Intuition is nothing more and nothing less than recognition.” — Herbert Simon

A while back, I stopped reading the AI’s end-of-task summaries and started watching the diffs. They came through faster than I could have typed them. I wasn’t reading them line by line — I was watching the shapes go by. Every so often one snagged. Not because I’d traced the logic; because it looked wrong before I knew why. I’d stop, look, and there it was.
Maybe that’s just me. It isn’t — it’s a trained reflex with a name.
That snag is expert pattern-recognition — the same thing that lets a chess master glance at a mid-game board and take it in at once. Give Away the Writing, Keep the Reading argued that reading is the durable skill now, and that there’s no checklist for it. What it didn’t do is say what that skill actually is, or how you build it. That’s this post.
BLUF: Bottom line up front
- Fast reading is trained pattern-recognition, not a knack — a reasoned bet from the expertise research, not a settled result (see How sure I am below). You can build it. Most engineers just never trained it on purpose.
- Read a lot of good code, against a mental model, with feedback. Good code, because the reflex forms on patterns you’ll see again — you build it on the idiomatic, not on slop. A mental model, because the catch is a violation of what you expected. Feedback, because without it you’re practising being wrong.
- Internalise the conventions. The chunking that makes reading fast only works on code that follows patterns you already know. Conventions aren’t taste; they’re what makes a codebase fast to read.
- Two gears. Fluent monitoring runs at diff-speed and catches the obvious, cheap. The deliberate deep read — seams, production, subtle intent — is the one you slow down for. Fluency powers the first; nothing skips the second.
What the reflex actually is
Chess is the classic case. In 1973 Chase and Simon had masters and novices reconstruct a board from memory: on a real position the masters were far ahead, and when the pieces were scrambled into a random arrangement the advantage collapsed towards the novice’s. Masters don’t see a scatter of individual pieces; they see a handful of meaningful chunks — familiar configurations they’ve met over and over — and a random board has none to catch. The skill isn’t raw memory. It’s recognition of patterns that mean something.
The same experiment has been run on programmers. McKeithen and colleagues (1981) had experienced and novice programmers reconstruct a program from memory and found the same shape: on a normal program the experts were far ahead, and when the lines were scrambled the gap all but closed. Their edge was in the idiom, not the characters — programmers organise what they know into chunks, and the chunks are built from convention. Shneiderman’s earlier work on program comprehension (1976) pointed the same way. That’s a big part of why convention-following code reads fast and slop reads slow: the reflex fires on the pattern, and slop has no pattern to catch.
So when a diff snags, that’s a chunk failing to match. You hold a model of what this code should look like — Ruven Brooks called it top-down, hypothesis-driven reading, back in 1983 — and the wrong shape is the hypothesis breaking. You don’t scan for bugs. You expect a shape, and the violation raises its hand.
Why “trained” is load-bearing, not a hedge
The honest condition is the reason a novice can’t do this. Kahneman and Klein (2009) — a sceptic and a believer who argued about intuition for years and then wrote up where they agreed — settled on two requirements for expert intuition to be real rather than lucky: the domain has to have valid cues, and you have to have practised with feedback. Miss either, and “intuition” is just confidence.
Code review clears both bars. That’s me applying their criteria to the job, not something they proved. The cues are valid: bugs have signatures, bad shapes recur. And there’s feedback to train on: a test goes red, a bug surfaces weeks later, a reviewer confirms the catch. Not all of it is fast, and plenty of defects stay silent — which is exactly why the deep read exists — but enough lands to build the reflex. So an engineer who has read a lot of code with the loop closed has a reflex worth trusting, and a beginner watching the same diff stream catches almost nothing. Same diffs, same speed. The difference is the reps. The instinct is built, not born — Ericsson’s deliberate practice, the same machinery as the chess player drilling positions.
Recognition, not derivation
This is where people want a shortcut past the practice. There sort of is one: you can work a diff out cold, reasoning through it line by line. It just runs too slow to keep pace with how much code now comes past. There’s no route to the speed that skips the reps.
What the reps buy you is a model to read against, and it works at two levels. The lower one is idiom: the right operator, the awaited call, the handled error. Checking those is mostly mechanical — which is exactly why a linter or an AI reviewer does it well. Catching a broken idiom is real work, but it isn’t the part that needs you.
The part that needs you is the model of what the change is for, and that model is built from more than the code. On a team you’re carrying the goals, the constraints nobody wrote down, the half-related work two projects over that this quietly breaks. So you catch the code that moves away from the plan — a call that should never run, three timers where one should do — where nothing is malformed and the diff reads fine on its own. An automated reviewer gets the same diff and the same codebase, but not the context that was never written down. It’s not that it can’t reason; it’s that it hasn’t got your grounding to reason from. Code-review research keeps landing on the same thing: the hard part of a review is understanding the change, not catching defects. That part stays yours.
So what you’re doing is simple: you look for the shape your model didn’t predict. The fast read is recognition, not always derivation. Often you don’t have time to reason all the way to the meaning; the pattern trips and you go look.
A ?? — nullish-coalescing, not a ternary — rolls past that returns a fallback when a lookup misses. It snags before you’ve reasoned it out. Then you look: the fallback is a valid-looking value, so a missing record becomes a real one, silently, and nothing downstream ever complains. You didn’t derive that. You recognised the shape of it and stopped.
Not everything that snags is a bug. Sometimes the author just did it a different way from the one you had in mind. The stop still pays: you look, and either you’ve caught something or you’ve picked up a pattern you didn’t have. Following the snag is part of how the model gets sharper.
// snags on sight: the ?? swallows a missed lookup
const rec = table[id] ?? { id, status: "active" };
// no error, no null — just a fabricated row nothing downstream questions
Sometimes it’s one specific pattern; sometimes several fold into a single sense that something’s off. It’s still recognition, and it’s still trainable. That’s why there’s no checklist. A checklist is a procedure, and this isn’t a procedure — it’s a reflex built from reps. You can’t hand someone the output of ten thousand reps as a bulleted list; if you could, the reps wouldn’t be the skill. Every “how to read code” guide that’s really a checklist is teaching the deliberate deep read — fine, and necessary — but the fast reflex only comes from the reps.
What the book is for
I wrote How to Think About Code the way I did for exactly this. The rules in it aren’t a rulebook to memorise; they’re scaffolding — the positions to drill so the recognition forms. A chess coach doesn’t hand you a flowchart for winning; they give you patterns to see until seeing them is automatic. The book is meant to be that, for code: a structured way to run the reps so the shape starts to jump out on its own.
The snag is the skill
Now that the machine writes the code, the reading is the job — and fast, trained reading is what lets you keep pace with how much of it there is. Reading as it lands also keeps you in the loop: a bug caught in the third file saves the six built on top of it, far cheaper than unpicking it at the end. It’s close to pair programming: you watch the code take shape and steer as it goes, instead of signing off a finished pile. The tool reads too; automated review is real and getting better — the idiom level is its natural home. But the calibrated eye and the accountability for what you ship stay with you. The tool assists. It doesn’t own. That eye is a property of you, built rep by rep — there’s no version you download. You read a lot of good code, against a model, with the loop closed, until the wrong shape snags before you know why.
That snag is the skill. The writing, the machine will do for you.
Sources
- Chase & Simon, Perception in Chess, Cognitive Psychology 4(1) (1973).
- McKeithen et al., Knowledge Organization and Skill Differences in Computer Programmers (1981) — normal-vs-scrambled program recall; programmers chunk code by convention.
- Shneiderman, Exploratory Experiments in Programmer Behavior (1976) — program comprehension and programmer behaviour.
- R. Brooks (1983) — top-down, hypothesis-driven program comprehension.
- Kahneman & Klein, Conditions for Intuitive Expertise: A Failure to Disagree, American Psychologist (2009).
- Ericsson, Krampe & Tesch-Römer, The Role of Deliberate Practice…, Psychological Review (1993).
- Bacchelli & Bird, Expectations, Outcomes, and Challenges of Modern Code Review, ICSE (2013) — the main challenge in review is understanding the change, not finding defects.
- Mäntylä & Lassenius, What Types of Defects Are Really Discovered in Code Reviews?, IEEE TSE (2009) — most review findings are evolvability/design, not functional.
How sure I am: Applying the expertise research to code review is a reasoned bet, flagged in the text — not an established result.
Related: Where the Reps Come From (the ledger of which reps you lost and how to get them back); Fluent in a Dead Idiom (what fast reading looks like when the idiom you’re fluent in has moved on); “Context Debt” Is a Strawman (deriving the context on demand instead of carrying it); The Nit Was Never Optional (the small call that used to be a rep, now held by a tool).
Reading series, part 4 of 4 (it begins with Give Away the Writing, Keep the Reading). The reps are the subject of the book, How to Think About Code.