Code readability depends on how well written code fits human working memory. Working memory handles only about four so-called chunks at once, bundles of information pulled from long-term memory. Good naming, short method signatures and avoiding side effects cut down the number of active chunks and make code readable for everyone on the team.
Key Takeaways
- Working memory can handle only about four chunks at once, which is why a method call with an object, a method and two arguments already hits that limit.
- Chunks in long-term memory aren’t uniformly small units: a single chunk can activate lots of detail at once, and that’s what makes abstraction so powerful.
- Good naming means the chosen term activates the same chunk in as many readers as possible, so it triggers associations similar to the author’s.
- State transitions in code overload the brain, because it can notice a change of state but struggles to replay it internally, which gives side-effect-free functional programming a cognitive edge.
- Pair programming synchronizes how two developers form chunks: whatever the navigator doesn’t understand is a reliable sign that others will find the code hard to read, too.
Code Readability Is a Matter of the Brain, Not Taste
Whether code is readable comes down to how well a human brain can process it. That’s the starting point for Stefan Mandel and Peter Guntermann, who put code readability on a cognitive footing. Both work as software developers and have spent a lot of time on clean code. Instead of simply accepting the rules from Robert C. Martin’s book, they went looking for the reasoning behind them: why do these recommendations work in the first place?
The problem that got them started is familiar to anyone who works in a team. A junior writes a method with four arguments, a senior colleague says you don’t do that, and when asked why, the best answer is a pointer to a book. That only goes so far. Nobody can know a thousand books by heart, and some of them even contradict each other.
The better answer sits one level deeper. Once you understand how the brain takes in code, you can work out good practices yourself and explain them to others. Instead of “you just don’t do that,” you can say: your brain is overloaded, so cut down the information.
How Working Memory Processes Code
When you read code, your brain handles only a limited amount of information at once. Stefan and Peter distinguish between working memory and long-term memory. Working memory is the part that actively computes as you step through a line of code, and that’s the part with tight limits.
The central unit here is the chunk. A chunk is a bundle of information stored in long-term memory. Every word in the code, every variable, method or class name, maps to a chunk like this. Anyone who has learned a programming language carries chunks for its grammar and can run the code in their head.
Working memory can handle only about four chunks at once. Psychology talks about four plus or minus one. From the fifth element on, things get really hard. Four is the limit, and anything below it is easy going.
That’s why a typical line of code stays manageable. An assignment involves an object, a method and an argument. That’s three chunks, and the result only appears at the end, so it takes up no space before then. Working memory handles three chunks with ease.
Experience Makes Chunks More Powerful
More experience doesn’t make working memory bigger. It makes the individual chunks more powerful. The four-chunk limit applies to everyone. What differs is how much sits behind a single chunk.
Chunks come in different sizes. In computer science, the closest concept is abstraction. Anyone who knows design patterns and hears the word “Observer” immediately has a picture of the underlying concept without walking through every detail.
The brain works differently from a computer here. It doesn’t just compute symbolically on the abstraction. The detail chunks underneath an abstraction fire at the same time. Four pieces of information at once, but each can carry lots of detail, so you can process far more in a single step.
Code Is Communication
Code is a form of communication, and the receiver needs the same chunks as the sender. You have a requirement, turn it into a feature and write code. Someone else reads it later, and that someone is often you, just a few weeks on.
A term like “Observer” only helps if the other person knows it. Use a chunk the reader doesn’t have, and you’re talking into thin air. Readable code happens when the chunks on both sides are wired up in a similar way and associated with the same things.
That has a practical consequence for teamwork. You don’t write for your own, possibly odd idea. You write for your teammates. So computer science involves a lot of communication work long before a single line compiles.
Why Descriptive Names Often Miss the Mark
Good naming means that as many people as possible understand the same thing by a term. Naming is known as one of the hardest problems in computer science, and for good reason. A name has to hit the right chunk in the reader’s head.
Descriptive names are often misunderstood, though. Some people think they’re no longer allowed to use short identifiers. That’s not true. An x for the x-coordinate is a convention, and nobody has to write xCoordinate. You can give the reader some credit.
The opposite mistake does just as much damage. If you can’t capture a concept in one word, you sometimes end up putting a whole sentence into the variable name. Every part of that name is processed as a chunk. If the name is too long, you’ve forgotten the beginning by the time you reach the end. Short and precise beats long and descriptive.
Long comments don’t fix this. An endless comment in front of a variable wears the brain out, because you have to read it carefully before you get to the code. A good comment is better than nothing. But if you can build the meaning into the name, that’s the better choice.
How Many Arguments a Method Can Take
The common advice of about two arguments per method follows directly from the four-chunk limit. When you read a method call, you don’t just process the arguments. You also keep in mind which method is being called and on which object.
So with two arguments, four chunks are already in play: the object, the method and the two arguments. A third argument makes five, and that’s where you lose readers who can’t cope with five.
There’s a way out. An abstraction that sensibly bundles two parameters brings the chunk count back down. The price is generality. If you deliberately want to keep a method flexible, you can’t invent a new abstraction for every call, and you have to leave the arguments side by side as equal chunks.
State and Side Effects Overload the Brain
Side effects are hard to follow because the brain is bad at replaying state transitions internally. If a method quietly increments a counter in the background, you have to hold that state in your head on top of the actual flow.
That’s exactly why functional programmers advise against side effects. A chunk can’t be rewritten at any speed you like. When you reassign a variable, suddenly a different value sits behind it, and the old association no longer fits.
“The brain is very well equipped to perceive changes of state, but not to reproduce them internally.”
(Stefan Mandel)
The same logic explains why high cyclomatic complexity is so tiring. You have to carry every condition that led you to a particular spot in the code. At some point, working memory is full of branches, you start pushing information out, and your results get sloppy.
Metrics Filter Out Noise but Don’t Replace Judgment
Software quality metrics are a useful but incomplete indicator of readability. They’re neither sufficient nor necessary, and now and then a metric can simply be gamed.
The common metrics are broadly in line with the chunk model. High cyclomatic complexity points, with some probability, to unreadable code. But there’s complex code that’s still easy to read, and there’s unreadable code whose problem lies somewhere else entirely.
Naming, for one, escapes every metric. No technique can judge whether readers will assume the right thing behind a name. Metrics do the legwork and filter out what’s obviously unimportant. When it comes to naming, though, any check can be sidestepped.
Readable Code as a Team: Synchronizing Chunks
Shared chunks come from shared experience, and the most important way to build them is simply to talk to each other. The brain creates chunks when you experience events. People who share the same events develop similar ideas.
Several practices aim at exactly that:
- Automate code formatting. A formatter makes sure the presentation doesn’t add to the reader’s load.
- Keep variables short-lived. A variable that lives longer than it needs to has to be buffered in your head the whole time. That overloads you and everyone else.
- Avoid abbreviations. Three-letter abbreviations are a classic. If they don’t help understanding, drop them.
- Use pair programming. If the driver has an odd idea of what makes a good chunk, the navigator notices right away. Both form the same chunk at the same moment, and this synchronized reinforcement creates shared understanding.
One pattern gives the weak spot away. If you can’t read your own code after two weeks, you created a chunk once while writing and never used it again. Stefan calls this ad hoc chunking: plausible in the moment, but never reinforced because it had no lasting value. If something is hard for the navigator to grasp, it’ll be hard for others too. That’s when it pays to sharpen the code.
What AI Assistants Add to Code Readability
AI assistants like Copilot help with understanding, but they tend to overproduce. Anything that can talk can also ramble, and an assistant will quickly bury you in suggestions. On the other hand, you can ask when something is unclear and get an explanation.
A self-experiment shows where the limits are today. Asked to make an example more readable, the tool reliably lengthened the names, stretched method names to several words and always added four lines of documentation on top.
The real joke was in the details. A method called “difference of squares” was supposed to compute x² - y², but it calculated (x - y) * (x + y) instead. Mathematically equivalent, but as a justification for the name, unreadable. The direct form would have been less efficient, but easier to understand.
AI tools produce explanations like these mechanically, not thoughtfully. For one other job, though, they’re useful right away: explaining a regular expression, exactly where humans tend to give up.
Frequently Asked Questions
How much information can a developer keep in mind at once while reading code?
About four. Working memory can process only about four chunks at a time, that is, chunks of information from long-term memory; in psychology, this is referred to as “four plus or minus one.” Starting with the fifth element, it becomes significantly more difficult. A typical assignment involving an object, a method, and an argument takes up three chunks and thus remains easily manageable.
Can experienced developers process more information at once than beginners?
No, the four-chunk limit applies to everyone. Experience does not increase the capacity, but rather the size of the individual chunks. Anyone familiar with design patterns who reads the word “Observer” immediately has the entire concept in mind without having to go through every detail individually. The detail chunks beneath an abstraction contribute to this, which is why four units can contain vastly different amounts of substance.
Are long, descriptive variable names always better than short ones?
No. An x for the X-coordinate is an established convention; xCoordinate offers no benefit: You can assume the reader is reasonably clever. The opposite mistake is just as harmful. If you pack an entire sentence into a variable name, you create many chunks because each word is processed individually. By the time you reach the end of the name, the beginning is already forgotten.
Are there cases where a method can handle more than two arguments?
Yes. Two arguments, together with the object and method name, already fill four chunks; a third one confuses readers. An abstraction that sensibly combines two parameters reduces the number again. However, it comes at the cost of generality. If you want to keep a method deliberately flexible, you can’t invent a new abstraction for every call; instead, you leave the arguments side by side.
Can a detailed comment compensate for an unclear name?
Only to a limited extent. A good comment is better than nothing, but a ridiculously long comment preceding a variable is tiring because it must be read carefully in advance. If the meaning can be conveyed in the name itself, that is the better choice. Brevity and conciseness trump a detailed description because they take up less space in working memory.
Are software quality metrics sufficient to ensure understandable code?
No. Metrics are a useful indicator, but they are neither sufficient nor necessary, and they can occasionally be tricked. High cyclomatic complexity indicates, with a certain degree of probability, that the code is unreadable. However, there is complex code that is highly readable. Naming defies measurement: no technology can assess whether a name triggers the right association in the reader’s mind.
Why do you sometimes no longer understand your own code after two weeks?
Because the corresponding chunk was created only once while writing and was never used again afterward. Stefan Mandel calls this ad-hoc chunking: plausible at the moment of writing, but not solidified. Shared chunks arise from shared experience. In pair programming, the driver and navigator create the same chunk simultaneously, and what’s difficult for the navigator to grasp is equally difficult for others.
Do AI assistants help make code more readable?
To some extent. They provide explanations on demand, but tend to overproduce. In a self-experiment, when asked for greater readability, the tool simply lengthened the names, expanded method names into multiple words, and consistently prefixed them with a four-line documentation block. A method named “difference of squares” calculated the equivalent form using parentheses, which rendered the name useless.


