Naming, Code Conventions & Glory

Mark Fainstein
Zencity Engineering
8 min readJul 27, 2021

* note: all code snippets below are based on a true story in Zencity’s codebase.

“I don't know what you mean by 'glory', Alice said.
Humpty Dumpty smiled contemptuously. "Of course you don't—till I tell you. I meant 'there's a nice knock-down argument for you!' "
"But 'glory' doesn't mean 'a nice knock-down argument'," Alice objected.
"When I use a word," Humpty Dumpty said, in rather a scornful tone, "it means just what I choose it to mean—neither more nor less."
"The question is," said Alice, "whether you can make words mean so many different things."
"The question is," said Humpty Dumpty, "which is to be master—that's all.”
― Lewis Carroll, Through the Looking Glass

Humpty Dumpty is — of course — a Nominalist. He believes that names are tags by which we can conveniently denote objects. In the following snippet by Humpty Dumpty, the names are merely tags (vaguely inferring types maybe):

Names as tags

So the question is… “which is to be master…?” As architects of castles in the air, do we have the mandate (like Humpty Dumpty) to name and define our rules of the game, our creations? Do we have the artistic freedom to express ourselves?

Pair Programming with Lewis Carroll

“I maintain that any writer of a book is fully authorised in attaching any meaning he likes to a word or phrase he intends to use. If I find an author saying, at the beginning of his book, "Let it be understood that by the word 'black' I shall always mean 'white,' and by the word 'white' I shall always mean 'black,'" I meekly accept his ruling, however injudicious I think it.”
― Lewis Carroll, Symbolic Logic

As always with Lewis Carroll, the real protagonist is the English language. The ‘author’, Lewis Carroll points out — has absolute ‘authority’ over meaning. So if you were to program with Lewis Carroll (oh … that could be fun!) — when you would ask for some guidance to understand a piece of code, you‘d definitely get the answer: RTFM (Read The Fucking Manual).

Lewis Carroll — RTFM!

Tea Party

The following banter probably takes place on a daily basis in your office (heck — it is probably happening in some office around the world right now!):

Developer 1: You’ll never be perfectly clear. Many times choosing a suitable name is just impossible. This is why JSDoc is your friend!

Developer 2: No amount of documentation can fix consecutively bad naming. What I don’t like about JSDoc is exactly this: it’s less important how I name variables because I’m writing a textual documentation for them (which becomes irrelevant the first time someone refactors that feature).

Developer 3: Documentation becomes outdated and then it hurts you more than helps!

Developer 1: Documentation doesn’t become outdated. If you update the code and not the documentation then it’s your mistake. Just like trying to use an API with outdated documentation — it’s the developer’s fault. Not all code (I would even say most) can be properly named and be self-explanatory.

… And the Slack thread continuous for eternity…

Wonderland & Reality

How many legs does a dog have if you call his tail a leg? Four. Saying that a tail is a leg doesn't make it a leg.
- Abraham Lincoln

Does naming even matter? One could argue — since it all boils down to bits eventually — that the question is purely a philosophical one. Nice for lunch, bad for productivity. You can play with Object Oriented Programming, Functional Programming, Names (PascalCase, camelCase, hyphen-case) — mix them all-together in a cocktail shaker. But the machine does what it does.

So why bother with conventions, naming, documentation, enforcing style? As long as the machine understands you — you’ll be fine. Right?

Through the Looking Glass

“Must a name mean something?" Alice asked doubtfully.
Of course it must," Humpty Dumpty said with a short laugh; "my name means the shape I am - and a good handsome shape it is, too. With a name like yours, you might be any shape, almost.”
― Lewis Carroll

Specifically with names (like Alice, Bob…), it turns out Humpty Dumpty is strictly a Realist. He believes names are more than tags — they convey information.

Most of us take the absolute opposite stance to Humpty Dumpty in real life. While we are Realists with words (when we say ‘glory’ — we mean exactly that and not ‘a nice knock-down argument’) — with names we are usually (not always) Nominalists. Surely we easily accept the fact that some names have no meaning at all, or very vague meaning.

Are we Nominalists or Realists when writing code? How much authority do we have? Are we responsible for how we are understood?

Humpty Dumpty Falls Into The Rabbit Hole

A Few Pull Requests by Humpty Dumpty:

I get it (or — are all getters created equal?)

Some getters are simple, just as this one — which is what we actually expect from a getter.

But what about this one?

Here is a method, where DataItemsProvider.getItems is used. But what is hiding behind it? We expect it to go get us something (clear and simple), but is this the case?

A deep dive reveals… it is actually a fall into a rabbit hole! (Ok, ok… maybe I am exaggerating!)

It is an asynchronous operation (meaning it happens in some unknown time in the future), and seems complex. We had to dive into the underlying implementation to find out (exhausting the minuscule mental capacity we still have left) — that it’s also an operation involving other methods… Should we trust a getter the next time we see it? Or are we now compelled to step into any getter we encounter?

Let’s refactor:

Refactor getItems->fetchItems

Recap of the refactor changes:

  • Don’t surprise your callers. If it’s not a simple get operation, then what is it? Since we are performing an asynchronous operation (querying the database), a “fetch” is more appropriate. Now when someone sees DataItemsProvider.fetchItems, he or she knows this is probably an async operation. Contrast this with getItems — retrieving a previously stored value from memory.
  • What about getProvider? Since its role is to decide which provider to use, a more suitable name would be resolveProvider(options).
  • Precise, clear, short names —GetItemsOptions → FetchOptions, forceToUseMongoProvider →useMongoProvider, perf →Timer etc.

Too Long or Too Short?

Reflecting on the previous quote by Humpty Dumpty (“my name means the shape I am…”), consider the following Pull Request:

We are lost while following the name of the first constant in the above code. As we see the number 10 at the end of the line, we try to decipher its meaning. Then we quickly follow through to the next line, but we have to dig in our minds to understand what ‘fb’ stands for. Eventually, after some thought, the context might come into play, guiding us to accept ‘fb’ as ‘Facebook’ in the context of datasources.

Acronyms heavily rely on context, and require a cache map ready to use in the reader’s mind. There are, as always, exceptions, but generally it makes sense to ditch them altogether, just like Elon Musk does.

On the other hand, our mental capacity and short term memory are so precious, we should convey as much meaning as possible in the shortest way possible (otherwise we will sooner than later lose our reader with long, descriptive names).

Leverage these two facts:

  • Meaning is heavily dependent on context.
  • We recognise words and entities by their shape and structure.

Wrapper Hell

Wrappers & containers usually popup when something is hard to define or name. How would I call this thing that wraps this item? Ok, Let’s go with ItemContainer. But it has to reside in this area, with those attributes, and be translated there. Ok — I have an idea, let’s call it ItemWrapper.

One thing leads to another, a wrapper is wrapping a wrapped object, which is contained in a containerised container. We’ve all been there…

Wrapper hell

Let’s refactor:

HTML is inspiring…

Recap of the refactor changes:

  • Every abstraction layer has a purpose (if it doesn’t then we can safely remove it). We recognised that the top wrapper actually handles translation, so the name now clearly reflects this fact.
  • Get inspired by a known model or naming convention (HTML structure in this example). This way you are building on top of a known mental model, eliminating the need to build a new one from scratch.

Caterpillar Zen

Coding… In Zen.

In reality, while you are instructing a machine with your code, your code is only one step in many iterations to come (and if not, why bother, probably your code is obsolete anyway!)

This also aligns well with the fact that most programmers don’t spend much time (thanks to Moore’s Law) optimising machine instructions. So if your code is just one step in an iteration, you optimise for readability most of the time, or the ability to change.

This is why I would argue you should rarely be a Nominalist when writing code. Like Alice eventually understands — words should convey a meaning, otherwise communication is impossible. To ensure this, here’s the arsenal we use at Zencity:

Linter / Static Analysis Tool (development environment & CI/CD):

  • In my experience, for most teams, this is the most effective way to fight entropy and enforce conventions/naming standards. If you can’t define the Linter rule, prepare for a hard time guarding it. So there’s either no convention, or it’s enforced on the Linter (automatic) level.
  • Don’t compromise on Linter only for the development environment. Development environments break, there’s always someone using a text editor (or Vim…), and the developer just now onboarding forgot to install your Linter plugin. Always ensure the Linter operates on the CI/CD level, on every push. A reasonable approach would be to check Linter errors on the diff against your main branch.
  • Regular Linter cleanups: once you add a rule, all the deviations from the rule are now errors. Don’t avoid adding rules for this reason (otherwise you will not be progressing anywhere). Just make sure you setup the time to clean it up, just like any tech debt.

Scaffolding

  • Give your development team the best starting point — a generated code that is state of the art in terms of conventions and readability.
  • When you have a scaffolding tool, the main components should be well defined and agreed upon. This greatly reduces the risk of deviation — going down another path to solve the same problem that can be reached by the beaten path.
  • The scaffolding tool also greatly reduces the mental load needed to select the right component for the problem, and saves a lot of time checking if there was a deviation from conventions.

Naming Committee

  • Support your naming efforts by creating a designated channel (Slack, eMail, etc.) to discuss them. This nurtures the culture that names are important, that they are the building blocks of communication inside the development team and also outside of it, and that they should be effective in describing the model behind the software.
  • A message in the channel usually goes like this: “I have this class that does that and that — I thought of this name but it’s so long and awkward… What do you guys think?”

Pull Requests

  • This is where new conventions are born and discussed. This is also the most important moment that you can catch a deviation, a movement towards entropy. This is the last line of defence.

--

--