Pick a Good Name
I've been fortunate to work on some long-running projects, and they always confirm the importance of choosing good names. In this post, I'd like to talk about my thoughts on what makes a name good.
There are only two hard things in Computer Science: cache invalidation and naming things. -- Phil Karlton
The importance of naming things seems abstract until you've done it badly a lot. Imagine a function like this:
def a(b, c)
d = b + c
d
end
This is often called 'golf code' because it requires few keystrokes to
type, relative to something more verbose. It's impossible to maintain.
Only the person who wrote the function knows what a
, b
, c
, or d
represent. Everybody else has to load the domain into their head every time
they see it.
Bad names make it difficult to search through the code. They make it difficult to talk about the code, because the name confers inaccurate meaning, or no meaning. They make it difficult to refactor or change behavior, because the name becomes a handle. Like a handle on a basket, when you've mentally reached for it enough times in a certain way, you become trained to do that forever.
In one application I've recently worked on, we had a domain concept, a core type of user, that was hard to understand. Why? In our code, it had three different names. One of those names represented the concept's internal meaning; the other two described different business terms for the concept that had evolved. This complexity is the problem.
Let's focus on solutions: what makes a good name? In my opinion, a good name is the only name that exists in the system, it is meaningful to the system, and it is informed by multiple perspectives.
The Only Name
This is the most important of the three points. A domain concept gets one name in your system. This takes work to maintain in a big project with multiple contributors.
Name hacking should be discouraged; it's better to have one imperfect name than two. If you find yourself with a different opinion, you might have an overloaded idea that needs to be broken apart.
Stick to this rule, and everything else will be simpler.
Meaningful to the System
What does it mean for a name to be meaningful to the system? It means naming it something that you can understand, and not inheriting a mental model from somewhere else. This can be achieved with aliases or local variables, concepts that are core to almost every language and framework.
Take this GraphQL query:
allUsers: allCustomersWhoUseOurProductsAPIRefactored {
edges {
node {
streetAddress: main_street_address
city: town
state: state_or_province
zipCode: zip_or_postal_code
}
}
}
On the right of the colons are the names defined by our third-party GraphQL API. On the left are the names that we want to use: cased for JavaScript, and meaningful to our system. This is a line in the sand: one side represents concepts from the outside world, on the other are the names we need to get stuff done.
Informed by Multiple People
Names have significance that is unique to each person. They're informed by the languages you speak, where you grew up, and your opinions. When choosing a name, I find pair programming invaluable. A pair can help me see that a concept is deeper or shallower than it first appears, and pick a better name. When not pairing, I'll workshop the idea with other developers on the team, or search other codebases for relevant conventions. I want my name to be as good as it can be.
This takes more time. But I think in the end, it leads to code that can scale. Scale beyond yourself, or your ten-person company.
Conclusion
Take the time to pick out a great name. Spend as much time on that as anything else you do when writing code. Make it the only name, meaningful to your system, and informed by other people. Future developers will thank you.