September 28, 2021
This article started its life as a tech talk in a monthly speaker rotation called the Artisanship Talks. These talks address the craft of software engineering . They’re a time for us to step back from the day-to-day of bugs, features, and pull requests to focus on the fundamental habits and skills that make us better engineers. We’re excited to start sharing these lessons in written form on this blog, with this inaugural post in the Artisanship Series.
At Samsara, we take pride in encouraging our engineers to learn new skills — and we’re hiring! Take a look at our open roles.
“For magic consists in this, the true naming of a thing.”
― Ursula K. LeGuin, A Wizard of Earthsea
We’ve all heard some variation of this engineering maxim:
“There are two hard things in computer science, cache invalidation and naming things.”
— Phil Karlton, via Martin Fowler
And it’s true! Naming is hard because language is hard, and most of us don’t have degrees in literature or creative writing. In this post, we’re going to talk about why it’s worth taking the time to get better at naming, and how you can improve at this critical skill.
Names are the signposts in code. Names imprint the intentions and goals of the developer into the code they are writing. While the logic of your code is written for a computer, names are for people.
Put another way: Names are the smallest possible unit of documentation. More time spent on names translates to less time answering questions from other engineers, or maintaining separate docs.
Developers spend far more time reading and modifying code than writing new code. When names in code are effective, reading code is faster and easier, and modifying code is safer. Time spent creating good names is a smart investment that always yields returns for your coworkers, and your future self.
Code is often difficult to name when it is:
Poorly scoped or ill-defined
Overly complex
Undifferentiated from existing code
When it feels impossible to name something, step back and figure out what you really want your code to do before you write any more of it. Consider whether the code itself needs some redesign before it’s ready to ship.
Put another way: what happens to a codebase without good names? Unhelpful names mean hard-to-read code, and that creates a cascade effect towards code rot:
The purpose of your code will be difficult and time-consuming to understand.
Developers using or maintaining your code will be confused and write more bugs.
Buggy code gets a bad reputation: developers will be scared to work on it, so it won’t be kept up to date with the rest of the codebase.
It will degenerate into tech debt faster than well-named code.
A name is good when it tells you what you need to know as you read the code. It should be:
Descriptive
Specific
In line with codebase conventions
Grammatical
Let’s walk through each of these characteristics in a little more detail, with examples to illustrate each.
A good name provides a reader with enough information
Include enough letters: When you’re writing code, it’s tempting to use ultra short names. After all, your function is short — the scope is small!
But if other engineers come along and add to your scope, things can get confusing fast:
*Disclaimers:
At Samsara, we use Golang, and this advice conflicts with the style used in Golang internals! Whoa! We respect the style choices of Golang’s core maintainers — but we’ve found that in our own codebase, using more letters has better outcomes.
In some cases, the length of your names could have a real impact on memory usage. Luckily for most web app and mobile developers, this isn’t something you generally need to consider.
Include relevant nouns: This modified code example is from the frontend code for a settings page in Samsara’s web app. Each line represents a component that we render on the page for users to interact with. But what kind of components are they?
Surprise: they’re all toggles!
Without looking at the definition of each component, you’d never know there’s a standard format for this settings page.
Here’s another example from a legacy area of Samsara’s codebase. What does this method do?
Names should describe what the code does, in detail. Let your names take up space — it’ll make for faster, easier code reading in the future.
A good name is unambiguous
A key function of Samsara’s products is distilling large volumes of sensor data into digestible reports for customers. The processing and aggregation code for these reports gathers data from many sources. Or… does it?
A common pattern is converting data from one form to another. Let’s make it easy to understand what we’re converting from and to.
Adding more words to describe what your code does is a start; but making sure your words are as precise and specific as possible is essential for a great name.
A good name fits within the context that a reader is already in
Use abbreviations and names that your reader will be familiar with:
Let’s look at an antipattern from Samsara’s codebase. We allow our customers to set up alert definitions that conditionally check events in our timeseries data. When we match a customer’s configured conditions, we generate what our backend code calls an “alert event”.
In our frontend code, however, it’s called an “alert incident”… except where it’s still called an “alert event”, or an “alert” with associated “alert details”, except for when those details are called “incident details” instead… 😵.
For a reader, this code is a minefield. Without tracing through each method’s call site, it’s almost impossible to know what we’re rendering or mutating. We could add detailed doc strings to each function — or we could let the names document our code for us. Consistent names for types and methods would solve this problem immediately.
A good name is understandable for the reader in a broader language context
Adding words to make your names more specific and descriptive can lead to long names. Keeping your names grammatically consistent keeps them understandable:
Use action verbs for methods:
Now you know what you’re aiming for in a name. But how do you make one? The following steps are my personal method — and research has shown that names created in roughly this way are more understandable to other engineers.
Clarify your concepts
Describe the work done by the code you’re naming, as specifically as possible.
It is helpful, especially the first few times, to do this out loud with someone who can ask you questions or push you to clarify further.
Generate a list of words that encapsulate your concepts
Use a thesaurus!
Lean on your existing codebase.
Select and order your words in a grammatical way
Choose words that encapsulate the essence of your code as specifically as possible.
Bias towards words your collaborators are familiar with, but don’t follow a naming convention that you find confusing.
Your name will generally use a fraction of the total words you’ve come up with.
Get feedback — ask for it explicitly!
Include names in your technical design docs and RFCs.
Get feedback in code reviews.
Solicit direct feedback from developers who will use your code.
Remember: Names are for people, so get input from people!
Creating one good name is a start, but how can develop your naming skills for the long term?
Practice & ask for feedback
Spend time on names intentionally when you’re designing and writing code.
Focus on names while reading code and technical design docs
Notice when a name tells you what you need to know, or doesn’t. If you find that you’re confused about some code’s purpose, you’re probably not the only one.
Expand your technical vocabulary
Read more technical writing from outside your own company. Companies develop their own internal shorthand for talking about their technologies, so make sure you’re hearing how other organizations describe similar concepts.
Expand your non-technical vocabulary
Read poetry! Poets distill big ideas down into just a few perfect words. Sound familiar? You can get a poem in your email inbox every day via the Poetry Foundation’s Poem of the Day newsletter.
Read more non-technical literature in general. Most software engineers aren’t published authors. Names are the tiniest possible unit of written communication. Why not learn from the best?
Good names cast a magic spell that protects your code from code rot, protects your coworkers from wasted time, protects your application from bugs, and will bring you fame and fortune. Naming is a skill that you can, and should, methodically work on and improve at over time. Your favorite coworker — your future self — will appreciate it!
A general writing style manual by William Strunk, with a now-famous introduction by EB White.
“How to name things: the hardest problem in programming”
A slide deck by Peter Hilton, with an exhaustive set of examples of good and bad names. Hilton has written fairly extensively about naming, and why it’s important, and how to get better. I recommend his work on naming if this is a topic that deeply interests you.