Chunking is essential
We split our code into chunks. First, functions, then classes, files, folders, and repos.
If the chunks are too small, you can’t read a complete thought anywhere and have to jump between chunks instead. The jumping adds cognitive overhead.
If the chunks are too big, you can’t read a complete though anywhere and have to jump around within chunks instead. The jumping adds cognitive overhead.
But when the chunk sizes approximately match the size of “one complete thought” in our brain, then we can read it easily. When we’re writing in English, we’re taught this early on: avoid run-on sentences, but also it’s jarring to have all four-word sentences. Group sentences into cohesive paragraphs that are big enough to convey an idea but small enough to convey only one important idea. Use section headings to group your paragraphs. Put a good title on the document to distinguish it from other documents. These are fundamentals of writing – imagine an untitled document with no section headers or paragraphs, but all sentences are five words or less. Or imagine a titled, sectioned document where each paragraph was a single, absurdly long sentence. We would immediately remark that this is unreadable.
So too with code.
If we chunk our code well, we can read it comfortably – even if the logic is complex and some of the syntax is unfamiliar.
Chunking requires editing
In code and in English, chunking is an editing task. The paragraph has grown too large, it must be split. These two tiny sentences would be more clear together as one. We should add a section heading here.
In code, we often guess the scope of a function or class incorrectly at first.
We tried to make a class that does one thing, but we’ve discovered it now does
three. The function had a narrow scope, but as it grew guard clauses (if
statements at the beginning of the function), it became long and complex.
If we care about editing for chunks that can be consumed by a human brain, we use standard refactoring techniques like extract method, inline method, extract delegate class, and move method. These let us shift code between chunks to make more sensible chunks.
Hard to edit means you edit less
Some languages and libraries make code harder or easier to chunk. The more effort and risk involved in editing (inlining and extracting) code, the less likely you are to do it. Since we can’t get good chunking without editing, ease of editing impacts quality of chunking; ease of editing impacts readability.
IDE Choice
Some IDEs support sophisticated automated refactoring, some do not. If your IDE does not make it easy to reshape your code, you’re less likely to reshape your code
Language Choice (typed vs not)
In general, languages without a type system are harder to refactor because our tools cannot reason well about the code. IDEs can offer better refactoring support for typed languages.
Framework (how much boilerplate)
Frameworks that require boilerplate for making “a new thing” prevent us from using our IDE refactoring tools to extract.
Example
For example, among browser UI frameworks, React and Angular differ in their
editability. In React you can extract part of a component into a variable,
then into a local function, then into a separate file. We use standard
refactoring techniques for this. In Angular, to make a new component you must
create a new @Component()
annotated class, which cannot access the methods and
variables in scope of the parent component. There is no lightweight extraction
path; your code must jump from part of the parent to part of a fully independent
component in a single grand leap. WebStorm provides a basic “extract component”
refactoring, but since it has to make decisions about TypeScript local
variables, HTML local variables, and constructor-injected dependencies, it often
guesses wrong at what you want. It usually creates something broken or a
component that relies on callbacks and prop-drilling, which are not idiomatic
Angular techniques.
Frameworks that use basic language features are more editable
The more a framework relies on the basic language constructs (functions, classes, etc.), the easier it is to apply standard tools and techniques for editing.
If a framework team is developing custom developer tooling to support their custom syntax, it is very unlikely that they will outpace the general developer tooling for that language. How could an individual team working on a custom syntax outpace a global community? Maybe there are exceptions for languages if the framework team is very well funded and the global community is not very involved.
By contrast, when the framework relies on basic language constructs, they can leverage the existing tooling for extracting/inlining code.
Code design (how much spaghetti)
Even with a strongly typed language, top-notch IDE refactoring support, and a tech stack that does not interfere with IDE/language refactoring tooling, you can still make it hard to edit your code by how you choose to arrange it.
For more on that, see So DRY it’s SCORCHED
Bottom Line
Pay attention to the friction that disencentivizes you to extract or inline code. The more you can reduce that friction, the more likely you are to edit. And then, edit like it’s a highschool English class essay: split your run-on sentences, make cohesive paragraphs, and choose good titles. Chunk well so you can read it well.