CodingJanuary 20, 20264 min read
Naming Things: The Hardest Easy Problem
USAMA DARWASHI

I once spent forty minutes of a design review arguing about one word: whether a core entity in our data model was a Measurement or an Indicator. It felt absurd at the time. It turned out to be the most useful forty minutes of that project, because the argument was never about the word. It was about what the system actually was.
If you can't name it, you don't understand it yet
Six years in, the pattern is remarkably consistent: when a name refuses to come, the problem is never vocabulary. The concept underneath is still mush. DataHandler, ProcessManager, doStuff(): these aren't names, they're confessions. They admit that something happens here, but nobody can say what.
When we built the Indicators reporting platform for Oman's telecom regulator, an early version of the data model had a table called values. Values of what? Submitted by whom? Raw or validated? Every discussion about that table ran twice as long as it should have, because each of us was quietly holding a different definition. The fix wasn't clever engineering. We sat with the domain experts and learned that the regulator distinguishes a submission, which is what an operator sends, from an indicator value, which is what survives validation and gets published. Two concepts, two names, two tables. Half the "bugs" in that corner of the system evaporated, because most of them were misunderstandings wearing a stack trace.
A bad name is not a style problem. It's a design smell that happens to be spelled in letters.
So when a name won't come, I stop typing and start asking questions. Within ten minutes someone usually says "well, it's actually two things" or "that only exists after approval", and the design fixes itself. The name was the diagnostic tool all along.
Rename early, rename often
Here's the strange part: the fix is almost free. Renaming is the highest-leverage refactoring in existence, and your IDE has turned it into a two-second operation. Rename symbol, run the tests, commit. No behavior change, no migration, no meaningful risk. Nothing else in the refactoring catalog comes close on cost-to-benefit.
Yet teams sit on bad names for years. I've watched engineers write comments explaining that customer in this particular service actually means the reseller, not the end user, instead of spending ninety seconds renaming it. Every comment like that is interest on a debt you could pay off before lunch.
My rule is simple: the moment you catch yourself explaining what a name really means, rename it. There are legitimate exceptions. An identifier that leaks into a public API contract, or a PostgreSQL column that a dozen reports query, is genuinely expensive to change, so weigh it. But inside your own codebase, hesitating to rename is choosing to stay confused on an installment plan.
Conventions are contracts, not preferences
Naming conventions get dismissed as bikeshedding, and the specific choices mostly are. Whether you write getUser or fetchUser matters far less than whether the whole team means the same thing by it. A convention is a contract: a promise about behavior, encoded in the name.
On Sabr, the analytics and monitoring platform we built for the telecom regulator, we agreed on a handful of these:
- Anything ending in
Repositorytalks to the database and nothing else. find*methods may return empty;get*methods throw if the thing doesn't exist.- Anything called a
Snapshotis immutable and safe to cache.
None of this lived in a wiki anyone read. It didn't need to, because the names carried the rules. A new engineer could trust a method she had never opened, purely from its signature. That's what a convention buys you: the ability to reason about code you haven't read.
The corollary: breaking a convention isn't a style violation, it's a broken promise. A getUser that quietly returns null lies to everyone who trusted the contract. Review it like a bug, because it will become one.
What Arabic taught me about names
I work in two languages. In Muscat, the domain conversations happen in Arabic while the code is written in English, and that constant translation is a naming stress test most teams never get.
When we built Mada, a tower-degradation analytics platform for Omantel, "degradation" seemed obvious in English. Then you try to say it in Arabic and the language forces a choice: تدهور is gradual worsening, خلل is a fault, انقطاع is an outage. Which one did we mean? The English word had been comfortably blurring three different concepts, and the models built on top of it blurred them too. The Arabic didn't add precision; it revealed the precision that was missing.
That's been my test ever since: translate the concept. If it survives the trip between languages with its meaning intact, it's real. If it dissolves into three words, it was never one thing, and your code shouldn't pretend it is.
Naming is design work. Budget time for it, argue about words in review, and rename without ceremony. The forty minutes are never about the word.