There are only two hard things in Computer Science: cache invalidation and naming things.
This is a quote attributed to Phil Karlton, a famous Netscape (now, that’s a trip to the past!) developer. It’s, without question, my favorite programming quote. I share it whenever I can (like now!).
On the surface, it seems like only one of those things is hard. That’s cache invalidation. It’s the process of removing invalid data from a cache. If you’ve ever built anything with WordPress object cache, you know that it’s not easy to do at all.
But naming things? Who struggles with that? That seems like the easiest thing in the world. And that’s true in a way. Naming something doesn’t take a lot of effort.
Here, I’ll even name three variables for you! They’re pirate
, wizard
and ninja
. You might wonder, “Why did he pick pirate, wizard and ninja as variable names?” No reason. They just sound awesome!
The point of using a silly example like that is to show you that you can name variables anything that you want. It’s not hard to find a name. The hard part is picking a good name. It needs to be clear and mean the same thing to everyone reading.
So what can you do to ensure that you’re naming things as best as you can?
Understand the problem that your code is solving
Imagine that you took a piece of code that you’ve been working on today. Could you explain what problem it’s solving to someone else? It’s not always easy to do that.
When you work on a problem, you’re often immersed in it to a point where it feels natural. But that feeling is deceptive. A lot of things about the problem start feeling obvious to you. This can make it hard for you to put the problem into words that others can understand.
Yet that’s exactly what you need to do. You should view the language around your code as your proxy. Its job is to explain the problem that your code is solving to others when you’re not around (which is most of the time).
To accomplish that, you might need to take some extra time to explore the problem in greater detail. This will help you flesh out the language around the problem. This should make it easier for you to describe what your code is doing to others.
Use words that everyone can understand
When you progress as a software developer, you start hearing about the different ways to code. For example, you have test-driven development. It says that you should always write unit tests before coding anything.
One of these design philosophies is “domain-driven design” (or DDD for short). It’s a popular way to code software with complex business requirements. When you code using it, you have to use what they call a “ubiquitous language“.
This is a core principle of domain-driven design. It’s the idea that software developers and business stakeholders should share the same language. Why would they want to do that?
Because doing that prevents issues where business requirements get lost in translations with developers. The developers have to use the same words as the non-developers in their code. Let’s look at a small example to put this in perspective.
Who is a user?
For example, let’s look at the word “user”. For developers, “user” is a word that we see and use all the time and the meaning is clear. It defines who uses the application that we’re coding.
But for a non-developer, this isn’t always something that’s clear or makes sense. Is the user a customer? Is it a company? What if we have more than one type of users? Are they all users?
As the developer, we know the answers to these questions. But, as you can see, it doesn’t take much to create confusion around the meaning of the word. That’s the problem that the ubiquitous language is trying to solve.
Empathize with others
It’s true that you’re not coding software with complex business requirements. But that doesn’t mean that there isn’t some merit to the idea of creating a ubiquitous language. That’s what the previous example tried to show you.
Creating a ubiquitous language forces you to empathize with others. You need to find words that aren’t ambiguous and that everyone can understand. The result is that it’s easier for others to work with both your application and your code.
This applies to you as well. As we’re coding and immersing ourselves in a problem, we often forget about our future selves. They might not remember every detail like they did when they worked on the code. And you know what? That’s ok!
We should also empathize with our future selves. They’re often not that different from someone who has to read your code for the first time. They both deserve a consistent language made up of words that are simple and unambiguous.
Be explicit in your code
So far, we’ve only looked at what you can do outside your code. But that’s not all that you can do. There are ways to improve naming in your code as well. A lot of it relates to what we’ve seen so far.
Clear names
Let’s go back to my silly example from earlier. Why aren’t pirate
, wizard
and ninja
good variable names? It’s because they aren’t clear to everyone. Well, that’s unless your application has pirates, wizards and ninjas. (In that case, you’re working on a pretty sweet application!)
Instead, focus on giving representative names to your variables. If your variable contains categories, you call it categories
. If it’s just one category, you call it category
. If you’re saving a product category, you call it product_category
.
That said, it’s important to not get carried away with it either. You don’t want to create long names just for the sake of it! There are times where a short name is fine. If your function only saves a product category, it’s ok to call the variable category
.
It’s also worth mentioning that this doesn’t only apply to variable names. You should do this with function and class names as well. Be as clear and explicit as you can be when naming anything.
Don’t use abbreviations
You should also try to avoid abbreviations as well. For example, let’s say you’re using cat
instead of category
. Does cat
mean a category or catalog? (or maybe it’s an actual cat!?)
Sure, you know the answer, but it still creates ambiguity. As we saw earlier, you should avoid it as much as possible. Saving a few characters isn’t worth the confusion that an abbreviation might bring.
Keep your functions and methods small
The size of a function or method also has an impact on your ability to name things. Keeping them small forces you to have them do one thing only. This focus makes it easier for you to find a name for them.
If you’re saving a category, call the function save_category
. If you’re saving more than one category, call it save_categories
. save_categories
could even call save_category
to save for each individual category. (Look at that sweet code reuse!)
The comment smell
Does your code have a lot of comments? Do you rely on comments to explain why you named something? This is a sign that there’s something wrong with how you’re naming things in your code.
You should see this as an opportunity to clarify the names that you use in your code. That’s because comments aren’t “free”. There are costs to excessive commenting.
For one, it forces you to switch between reading contexts all the time. Each time that you read a comment, you need to switch from reading code to reading text. Once you’re done reading the comment, you need to switch back to reading code. This is taxing if you have to do it a lot while trying to follow what the code is doing.
Which brings us to another point. If you have a lot of comments in your code, you have to keep them up-to-date as your code changes. Otherwise, your comments start being out of sync with what the code is doing.
If that happens, your comments end up causing more problems than they solve. Your reader is stuck double-checking whether your comments are accurate or not. This creates even more back and forth between reading text and reading code.
And the truth is that it’s not what we want to do when we’re working with code. We want to read code as much as possible. The real role of comments is to explain things that you wouldn’t be able to make out by reading the code.
It’s about writing well
If you consider programming to be a subset of writing, and I certainly do …
We often forget that writing code isn’t just about solving problems. We’re still writing something that others will read. That’s the essence of why naming is important when you write code.
It’s ok if you’re struggling with what you saw in this article. (That’s why naming things is hard!) You shouldn’t let that stop you. Instead, you should use this as an excuse to take a step back.
Go back to your problem and explore it further. You might discover new sides of it that you hadn’t seen before. This will help you flesh out the language around it. You’ll add new words that you can use to name things.
Thanks to Dennis Snell for reading the draft of this post and for his additional insights.