What is the Point?
The point of good naming is not “to have good naming.”
Nor is it “to have followed the rules.”
Nor is it “standardisation.”
When people reduce the art of naming to rule-following and source-quoting, they have lost the point of this whole exercise.
The Compiler Doesn’t Care
You and I can express the same programming concept in dozens of different ways, even inside a single programming language. Some ways are more efficient, more obvious, more elegant, more robust, or more pleasing than others.
All those ways will work for the compiler.
Occasionally, specific names may be required by a framework. Then tends to be the case when the framework creators make the questionable choice of using reflection. We have to comply with their naming standard in order for our software to work.
In other cases, names don’t matter to the underlying technology.
1 def a8f4e2c1(b7d9c3a5: int) -> List[str]:
2 e2b6f9d4: List[str] = []
3 for c1e4a8b7 in range(1, b7d9c3a5 + 1):
4 if c1e4a8b7 % 15 == 0:
5 e2b6f9d4.append("FizzBuzz")
6 elif c1e4a8b7 % 3 == 0:
7 e2b6f9d4.append("Fizz")
8 elif c1e4a8b7 % 5 == 0:
9 e2b6f9d4.append("Buzz")
10 else:
11 e2b6f9d4.append(str(c1e4a8b7))
12 return e2b6f9d4
The (pseudo)compiler doesn’t care.
So why bother choosing “good names?”
How Does it Matter?
If all practices are equally effective, the only reasonable standard is to use personal preference. If all code will only be read, debugged, tested, and used by compilers then names don’t really matter.
But that’s not how it plays out.
For one thing, LLMs benefit from good names. An agent’s ability to derive meaning from code is affected by the validity and clarity of the names used in the code. Better names are more efficient and burn fewer tokens.
Your agentic refactoring will be more effective if the code is better named and clearly structured.
As an additional wrinkle, we can’t trust our coding agents. We certainly can use them to our advantage, but we also need to examine their output to ensure that they are doing the right things, and only the right things. We have to read their code, and they have to read ours.
For that matter, the same is true of our human developers.
Face it, people do things in the worst ways when their entire focus is just getting some task off their plates. Plate-emptying is a common practice when people are in a big hurry (often an imposed hurry) and people feel there is no time to “do it right.” They are content to do it wrong, quickly, and leave it for someone else to deal with later.
The speed with which humans can correctly make sense of the code and remediate it will often decide if it’s going to be a bit of proper engineering, or a plate-emptying hack.
When something unexpectedly goes wrong in the middle of the night, will you (and your tools) be able to find, understand, and fix the problem?
Who takes responsiblity for the quality of the program and for its continuing operability? Will the plate-emptying person engineer a solution, or are you looking at a patch on top of a yet another patch[^1] ?
[^1]: Kris Cook once referred to a piece of software as being like a bicycle tire that had been patched so repeatedly that it no longer fit through the fender.
You need source code that works for all people and non-people who are active in the codebase.
We have this idea, which we feel shouldn’t be controversial:
How we do our work makes a difference.
We think the way to achieve different (better) results is to do the work differently.
Good naming in source code is essential for rapid comprehension, maintainability, and software quality.
- Well-chosen word identifiers improve speed to find defects (by nearly 20%)
- Descriptive identifiers speed accurate source code comprehension.
- Where good naming is used, less documentation is necessary (including comments)
- Poor identifiers are associated with low-quality code (although this may be a tautology, since poor naming is flagged by lint tools as poor code).
Since it does make a difference, we need to understand why and how.
Features of Good Names
Humans read, write, debug, and review code. Even when some AI is used to help generate the code, it’s humans who are held accountable. The AI can’t take responsibility for programs.
Benner’s Principles
Tom Benner wrote a pragmatic and helpful book called “Naming Things: The Hardest problem in software engineering.”[^2]
I recommend this book for further reading, and I will present some nuance here that isn’t present in that volume.
[^2]: add isbn and such here
Benner gives us four criteria that are crucial, which I will paraphrase slightly for our purposes:
- Understandability: The name is known, or needs to be known, by the reader to describe the concept it represents.
- Conciseness: The name has as few words as possible without sacrificing understandability.
- Consistency: Names are used and formatted consistently.
- Distinguishability: Each name stands out as different from the names around it.
There is nothing wrong with any of these suggestions. They are well-explained and the examples and rules that follow are great.
I will lean more on relational, hierarchical, and incremental aspects, hopefully without conflicting with either my work in Clean Code, or Tom Benner’s work in Naming.
Who Cares?
The reason for having a “good” name is that it speeds humans in their work.
- We want people to find the code they need to change, and find it quickly.
- We don’t want them to make errors due to misunderstanding the code.
- We don’t want to spend a lot of time explaining the code.
Everyone who will be tasked with understanding this code, whether to extend its functionality, correct a flaw, or improve its performance, cares about the naming whether they admit it or not.
You care.
And it’s up to you to care for others.
And now, the question is. “which others am I to consider, and how?”