Engineering At Samsara

Your Codebase Deserves Better Names

September 28, 2021

facebook twitter linkedin email

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

🥺 Naming is hard

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.

⚠️ Why is naming important?

🔮 Names create meaning

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.

⏳ Good names let you work faster

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.

🦜 Names are the canary in the coal mine

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.

☢️ What are the consequences of naming something poorly?

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:

  1. The purpose of your code will be difficult and time-consuming to understand.

  2. Developers using or maintaining your code will be confused and write more bugs.

  3. 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.

  4. It will degenerate into tech debt faster than well-named code.

🧬 What are the characteristics of a good name?

A name is good when it tells you what you need to know as you read the code. It should be:

  1. Descriptive

  2. Specific

  3. In line with codebase conventions

  4. Grammatical

Let’s walk through each of these characteristics in a little more detail, with examples to illustrate each.

Descriptive

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:

namingcode1

*Disclaimers:

  1. 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.

  2. 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?

namingcode2

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?

namingcode3

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.

Specific

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?

namingcode4

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.

namingcode5

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.

In line with codebase conventions

A good name fits within the context that a reader is already in

Use abbreviations and names that your reader will be familiar with:

namingcode6

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… 😵.

namingcode7

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.

Grammatical

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:

namingcode8

Use action verbs for methods:

namecode9

🖋 How to come up with a great name

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!

🥇 How to get better at naming

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?

🧙‍♂️ Conclusion

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!

📚 Appendix

Inspirations & Additional Resources

The Elements of Style

  • 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.

facebook twitter linkedin email