There are only two hard things in Computer Science: cache invalidation and naming things.
-- Phil Karlton
Naming things is hard.Image taken from [How to Name Things](http://slidedeck.io/hoontw/naming-things), used under [license](https://creativecommons.org/licenses/by/4.0/)
As developers, we spend a lot of time and effort trying to name things appropriately. This can cause us no small amount of frustration, as the ability to name things properly requires abilities (a mastery of your primary spoken language, a larger vocabulary, etc.) that aren't necessarily "part of the job" for everyday developers.
Still, good naming is a critical skill. Code is useless if no one else can read it, and so we must name our variables and functions, our methods and resources appropriately so someone (probably future you) can find and understand them again later.
Because naming is so difficult, it helps to have a particular set of rules to follow, even if you can't always abide by all of them. So, I present to you the
totally not made up Ten Commandments For Naming Your Code!
Ten Commandments For Naming Your Code
- Thou shalt be specific.
- Thou shalt not use unnecessary words.
- Thou shalt not use abbreviations.
- Thou shalt use the code's primary human language.
- Thou shalt not make up words.
- Thou shalt not include type.
- Thou shalt only use non-obvious words if the meaning is obvious.
- Thou shalt prefer active voice.
- Thou shalt use consistent syntax.
- Thou shalt break these rules if necessary.
Let's investigate each of these commandments to better understand what they mean.
Thou shalt be specific
The entire purpose of naming is to impart meaning. We should be able to have any programmer of any skill level be able to read our code and understand what the objects represent, even if they don't yet know how everything fits together.
We cannot convey the correct meaning without being specific. Take this string for example:
string name = "Jack";
What kind of name is this? A first name, a last name, a middle name, something else? Does it make a difference? A person who has no experience with this code will not know what precisely this variable means. If this string is, in fact, something more specific than just a name, then we should add more specific wording:
string monkeyName = "Jack"; //We named the monkey Jack!
Thou shalt not use unnecessary words
Don't go overboard on being specific, though. There's no reason to include words that don't directly add meaning to the name; they're just noise. Consider:
double interestRateForDatabaseStorageAndPaymentCalculations = 0.05;
Well, that sure is specific. But will interest rate ever not be used for "database storage" and "payment calculations"? Most of those words could be considered extra, so we could reduce the name down to this:
double interestRate = 0.05;
By naming this variable more descriptively, we've significantly reduced the likelihood that another programmer will not understand what this value represents. The more they understand, the more quickly they can start contributing to the code themselves.
To be fair, using the first two commandments together provides a fine line for anybody to walk. Only experience and failure will let us inch closer to the ideal of being specific without being long winded.
Thou shalt not use abbreviations
There is no guarantee of whether another programmer will understand what a particular abbreviation means, but there is a guarantee that at least one person won't. Consider:
int dpaTotal = 2000;
dpaTotal stand for? We have no idea, and unless we're intimately familiar with this code base already, we are unlikely to uncover what this abbreviation actually means just from reading the nearby lines. Instead, ditch the abbreviation and write out the words that the abbreviation is hiding:
int downPaymentTotal = 2000;
Now we have a much better grasp on what is going on here: this is a down payment amount, and we don't need to go digging further into the code to understand what information this variable holds.
Thou shalt use the code's primary human language
If the rest of the codebase is written in English, write your code in English. If the codebase is written in Farsi, in Zulu, in Wingdings or however your team communicates with each other, use that same primary language. There's no reason to have Spanish words show up in a codebase written in English; no debemos que ser bilingüe para leer el código.
Thou shalt not make up words.
Don't do this:
var grafutie = "10M-12F" //What's this mean?
Making up words forces developers who are new to the codebase to ask someone what the word means, and nobody wants to waste time trying to figure out what flagranvoci serit hansaio gerotaman.
Thou shalt not include type.
Also known as: don't use Hungarian Notation.
Adding a type or prefix of any kind (especially if it is abbreviated) generally adds to the length of the name without also imparting additional meaning. In many languages (and IDEs, and environments, and so on) the type will be obvious from the usage or declaration, so including type in our names is just adjExtra nounNoise prnounWe vrbMust advMentally vrbFilter nounOut.
Thou shalt only use non-obvious words if the meaning is obvious.
This is perfectly fine:
for(int x = 99; x >= 0; x--)
In this case, x is only being used as an iterator, and has no further meaning. A fellow programmer will most likely read this line and understand what
x is being used for.
Of course, if the X actually did have a more important meaning that just being an iterator, we should name it appropriately:
for(int bottlesOfBeerOnTheWall = 99; bottlesOfBeerOnTheWall >= 0; bottlesOfBeerOnTheWall--) //Take one down, pass it around!
Thou shalt prefer active voice.
In a sentence written using active voice, the thing doing the action is the subject of that sentence. Active voice shows that an action is being done by an object. An example might look like this:
public void Transmogrify()
The word Transmogrify is written in active voice, showing that this method will transmogrify something. This is opposed to passive voice, which looks like this:
public void GetTransmogrification()
In this snippet, GetTransmogrification is passive; it does not infer exactly how it will get the transmogrification. There will be times where we will need passive voice, but usually, since our code will be doing the action, we write our code using the corresponding active voice.
Thou shalt use consistent syntax.
Regardless of which syntax rules are in use in your the project, use the same one.
If all variables start with an underscore, our variables should start with an underscore. If all classes contain the word Class, ours should as well. Even if the existing syntax violates some of the other commandments, we should still use it, because being consistent is more important than trying to impose rules on a system that isn't using them already.
If you are in a position to change or influence the syntax rules you are using so that they are more consistent (or more sane), do it. Otherwise, suck it up and write your code so that it looks like all the other code in the project. A codebase should be written in a single, consistent style, no matter what (or how stupid) it is.
Thou shalt break these rules if necessary
You don't have to listen to me. There's no substitute for critical thinking. No set of guidelines will cover every possibility, and these are not the exceptions to this rule. Follow these "commandments" whenever feasible, but if you must break them, do so and don't fret about it.
Naming is hard, yes, but it is not impossible. By putting a little extra effort into devising good names, we improve our code's readability immensely. Trust me, the time spent thinking about good names is worth it. Future you, and any other developers that inevitably will end up maintaining your code, will thank you for it.
Do you know of any naming guidelines that I may have missed, or that have helped you solve your naming issues? Are any of these "commandments" more important than the others? Let me know in the comments!