Skip to main content
Start your own AI-powered blog — freeGet started →

Why Naming Things Is the Hardest Part of Coding

Why Naming Things Is the Hardest Part of Coding
Photo by cottonbro studio on pexels

Why Naming Things Is the Hardest Part of Coding

I once spent forty minutes naming a function. The function was four lines long.

My teammate watched me rename it three times in the PR and finally asked, gently, if I was okay. I was. I just knew something he'd later agree with: that name would be read a thousand times and written once, and I was the only person who'd ever get to choose it.

Naming things is the hardest part of coding. Not the algorithms. The names. Here's why, and how I finally got less bad at it.

Quick Answer

Naming is hard because a good name is a compressed explanation — it has to carry intent, scope, and contract in a few characters, to a reader you'll never meet, who has none of the context you have right now. It's not a typing problem; it's a thinking problem. If you can't name something cleanly, you usually don't understand it cleanly yet. The name is the test.

The old joke is actually a warning

You know the joke: there are only two hard things in computer science — cache invalidation, naming things, and off-by-one errors.

We laugh and move on. But naming earned its spot on that list, and we treat it like the throwaway.

A name is the only interface most people will ever have with your code. Most developers will never read the body of calculateUserDiscount. They'll read the name, trust it, and move on. If the name lies — if it actually calculates and applies the discount, mutating state as a side effect — you've planted a small bomb in everyone's mental model.

That's the real weight. A name is a promise you're making to every future reader, including yourself at 2am during an incident. It's one of those quiet craft skills that separate working code from senior-level code — the same theme I dig into in the brutal truth about becoming a senior developer.

A whiteboard covered in notes and diagrams Photo by cottonbro studio on Pexels

A name is a compressed explanation

Here's the thing that finally made it click for me. A good name does the job of a comment, but it can never go stale, and it gets read every single time the symbol is used.

code
// the comment most people would write
// gets active users who haven't logged in for 30 days
const u = getUsers();

// the name doing the comment's job
const dormantActiveUsers = findActiveUsersIdleFor(30);

The second one needs no comment. The name is the documentation, and it's documentation that can't drift away from the truth, because it lives right on the thing it describes.

That's also why it's so hard. You're not labeling a box. You're compressing a whole explanation — what it is, what it returns, what it promises not to do — into a phrase a tired human can parse instantly. Compression is hard. Lossless compression that survives six months and three teammates is brutal.

The name is a test of your own understanding

This is the lesson that changed how I work. When I can't name something, it's almost never a vocabulary problem. It's a comprehension problem.

If a function resists a clean name, it's usually because it does two things. validateAndSave. processData. handleStuff. The word "and" in a function name is a confession. The vague noun "data" is a shrug.

The struggle to name it is the design feedback. The code is telling you the boundaries are wrong.

So now, when a name fights me, I stop fighting the name and fix the code:

  • validateAndSave becomes two functions, validate and save, and suddenly both are easy to name.
  • processData was hiding three responsibilities; split out, they're parseCsvRows, normalizeAddresses, dedupeContacts.
  • handleStuff had no business existing.

The name didn't get hard by accident. It got hard because the code was muddy. The name was just the messenger. This is the same instinct that makes a good code review rule change a whole team: the friction is feedback, not an obstacle. Even MDN Web Docs leans on this — its readability guidance treats naming as a core part of writing maintainable code, not a cosmetic afterthought.

If you can't name it, you don't yet understand it. The naming pain is a design review for free.

The patterns I actually use now

After enough forty-minute naming sessions, I stopped relying on inspiration and started using rules. These are the ones that earn their keep.

1. Booleans read like questions. isActive, hasPermission, canRetry, shouldRefresh. If you can put it after "is the user…" and it makes sense, you've named it well.

2. Functions are verbs, values are nouns. user holds a user. getUser fetches one. Mixing these is how you end up with a "config" that's secretly a function.

3. Match the name to the abstraction level. Low-level code can say buffer and offset. Business code should say invoice and customer, never obj and data. The name should sound like the layer it lives in.

4. Length should match scope. A loop index living for three lines can be i. A value that lives across a 200-line module needs to earn its keep with a full, descriptive name. Tiny scope, tiny name. Huge scope, generous name.

5. Avoid the noise words. Manager, Helper, Util, Data, Info, Processor. They feel like they mean something and mean nothing. A UserManager that does nothing a User couldn't is just a place where responsibilities go to hide.

6. Name the concept, not the type. A list of users is users, not userArray or userList. The reader can see it's a list; what they can't see is that it's the active users, or the invited ones. Spend your characters on the meaning the type can't carry, never on repeating the type itself.

7. Be consistent across the codebase. If you fetch with getUser in one place, don't fetchAccount in another for the same idea. A reader builds a vocabulary from your code, and every synonym you introduce is a tax on that vocabulary. Pick one word per concept and hold the line everywhere.

Weak nameWhy it's weakStronger name
dataWhat data?pendingOrders
handleClickHandle it how?submitCheckout
flagFlag for what?isEmailVerified
UserHelperHelper is a non-wordUserMailer
tempTemporary foreverunsavedDraft

A focused developer reviewing code on multiple monitors Photo by Daniil Komov on Pexels

Renaming is the cheapest refactor there is

Here's the part I wish someone had told me earlier: you don't have to get the name perfect the first time.

Modern editors and developer tools rename a symbol across a whole codebase in seconds. The cost of a rename is near zero. The cost of living with a lie for a year is enormous.

So the move is: name it good enough to keep moving, and rename it the instant a better name reveals itself. Naming isn't a one-shot ceremony. It's a thing you tidy continuously, like making your bed.

The only sin is defending a bad name because you've gotten attached. Names are cheap to change and expensive to misunderstand. Optimize accordingly.

I keep a tiny ritual for this: whenever a name confuses me — the person who wrote it — I rename it on the spot, before I lose the context. If present-me is confused, future-me and every teammate are doomed. The confusion is the cheapest signal I'll ever get, and it expires fast. Catching it in the moment costs seconds. Discovering it during a 2am incident costs everyone.

There's a deeper payoff too. The discipline of naming well leaks backward into your design. When you commit to giving every function an honest, single-responsibility name, you stop letting functions quietly grow three responsibilities — because you'd have to name the mess, and you can't. The naming standard becomes a design standard. You write cleaner code not because you decided to, but because the bad designs no longer have anywhere to hide.

The bottom line

Naming feels like a small thing, a cosmetic flourish you do after the "real" work. It isn't. It's the place where your understanding of the problem gets written down in the most-read, longest-lived form it'll ever take.

Code tells the computer what to do. Names tell the humans what you meant. The second audience is the one that maintains it.

Get good at naming and a strange thing happens: your designs get cleaner, because you can no longer hide a muddy idea behind a vague label. The name won't let you.

If naming as a design tool resonates, try treating your next confusing name as a free design review — and stick around for more of these craft notes on leveling up as an engineer.

So next time a name won't come — don't push through it. Stop and ask what the code is trying to tell you. What would you have to change for the perfect name to be obvious?

Key Takeaways

  • Treat naming as a design tool: if a function resists a clean name, it’s likely doing too much—split it into single-responsibility functions to make naming (and the code) obvious.
  • Use boolean names as questions (e.g., isActive, hasPermission) and functions as verbs (e.g., getUser, not user); avoid noise words like 'Manager' or 'Helper' that obscure intent.
  • Match name length to scope: short names for tiny, local variables (e.g., i in a loop) and full, descriptive names for module-wide or cross-file concepts (e.g., dormantActiveUsers).
  • Rename early and often—modern tools make it cheap, while living with a misleading name costs time and clarity; if you are confused by a name, rename it immediately before context fades.
  • Compress intent into names: a good name replaces a comment by conveying what it is, what it returns, and what it promises not to do—e.g., findActiveUsersIdleFor(30) over getUsers().
  • Enforce consistency: pick one term per concept (e.g., always getUser, never fetchAccount for the same idea) to build a shared vocabulary and reduce cognitive load for readers.

Frequently Asked Questions

Should I use short names or long descriptive ones?

Match length to scope and to how far the reader is from the definition. Short for tiny, local, obvious things. Long for anything that travels. A name's job is to spare the reader a trip to the definition — pay whatever characters that costs.

Are naming conventions like camelCase vs snake_case worth arguing about?

No. Pick whatever your language and team already use and never bring it up again. Consistency beats correctness here. The quality of names matters far more than their casing.

Is it okay to use abbreviations?

Only ones your whole domain already shares — id, url, http. Invented abbreviations like usrMgr save four characters and cost every reader a guess. Bad trade.

How do I name something genuinely new with no precedent?

Describe what it does in plain words to a rubber duck, then compress that sentence. Often the verb and noun you naturally reach for are the name. If even the sentence is fuzzy, your design is fuzzy — go back a step.

Should AI tools name things for me?

They're a great first draft and a good thesaurus. But they don't have your domain context, so treat their suggestions as a starting point, not a verdict. The understanding still has to be yours.

A
Assisters

2 followers

AI assistants platform by Misar AI. Building the future of AI-powered automation.

Comments

Sign in to join the conversation

No comments yet. Be the first to share your thoughts!

More from Assisters

Recommended for you