An opinionated (and mainly correct) guide to naming

nephrenka1 pts0 comments

An opinionated (and mainly correct) guide to naming

Code for Humans and Machines

SubscribeSign in

AI-Readable Code<br>An opinionated (and mainly correct) guide to naming<br>Naming in software goes way beyond any aesthetics. Good naming minimizes reconstruction work. Here is the style and habits that I've picked up.

Adam Tornhill<br>Jun 23, 2026

Share

Today we’re taking on the second hardest problem in computer science: naming.<br>Each time we write code, we face a multitude of micro-decisions. How do we label functions, classes, variables, etc. to get the most out of the code as a communication medium? That is, communication that sharpens our thoughts in the moment, as well as code that supports our future selves and any agent trying to make sense of what’s already there.<br>As such, naming in software goes way beyond any aesthetics. Good naming minimizes reconstruction work. For both humans and machines.<br>In this article, I share the style and habits that I’ve picked up. It’s a style that evolved over the years, and shaped by viewing software through the lens of cognitive psychology to support the way we think, reason, and solve problems.<br>Why naming matters

Names are cognitive compression mechanisms. Design elements with strong names stretch the amount of information you can hold in your head at once.<br>Further, when reading unfamiliar code, we try to infer the purpose by building up mental representations. This process is largely driven by the names of classes and functions. The stronger the names, the easier the process.<br>And this translates into time savings, too. For example: clearer identifier names cut debugging times by 19% alone.<br>AI-assisted development benefits too. A recent study investigated the structural elements that contribute to LLM code understanding. Improving identifier names consistently yielded the largest returns.<br>Optimize function names for calling context

Most naming advice focuses on the declaration site. However, we read call sites far more often than declarations.<br>Consequently, we should communicate context via names. Let the names combine to build sentences in the calling context:<br>notify_all(registered_clients, about=the_new_version)Turning our function calls into sentences has cognitive reasoning benefits: that one sentence serves as a chunk. It becomes an abstraction that allows us to squeeze much more information into our cognitive working memory. That way, reasoning improves.<br>Derive names via wishful thinking

Now, let me share a trick that has helped me get this naming right over the years: the beauty of Wishful Thinking. Wishful Thinking in this context is a design tool that I learned about from the uber-classic Structure and Interpretation of Computer Programs. The idea is to write code as if the abstraction already existed. Pretend. Then, once the ideal sentence has taken shape, you go ahead and implement those functions. Naming comes first.<br>The reward is code that reads close to natural language without becoming verbose. That helps bridging the gap between the problem we’re trying to solve and the solution we express.

Subscribe

Let domain types liberate your parameter names

A function name is incomplete without its arguments. Yet too much code misses that opportunity.<br>A common reason for that is the code smell primitive obsession: representing domain concepts using primitive types. Consider:<br>public ActionResult ListRss(int languageId) {<br>...<br>public ActionResult NewsItem(int newsItemId) {<br>...While an RSS feed and a News item are clearly separate domain concepts, the code models both as raw integers. Besides weakening the type system, that code also fails to clarify context and intent. What roles does the news item play? Was it clicked by a reader, or selected to feature on a front page?<br>Introducing proper domain types lets us solve both problems. When the types capture the domain, they also liberate the variable names. Those names can now be repurposed to communicate context:<br>public ActionResult ListRss(Language preferredRssFeedLanguage) {<br>...<br>public ActionResult NewsItem(NewsItem clickedArticle) {<br>...<br>}The types tell us what the arguments are. That frees the parameter names to tell us why they’re there.<br>Scope determines length

We get told that we should let our variables explain exactly what they do. This naturally leads to longer names. However, like all programming “rules”, the soundness of that advice depends on context. Names don’t carry meaning in isolation. They expand on their surrounding context.<br>So, variable naming should reflect scope. The smaller the scope, the shorter the variable name. (and vice versa).<br>As an example, consider the following:<br>for i, article in enumerate(front_page_articles):<br>publish(article)An i might be perfectly fine in that short, tight loop or in a lambda function. The whole block serves as one logical element, one chunk.<br>It also follows from the same principle that a one letter name is detrimental in a larger scope such as an instance...

names naming code context domain types

Related Articles