The Art of Naming
Jasper Woudenberg May 3 '17
Putting some thought in what to name our variables and functions can make our code so much clearer, but if it proves very hard to give a clear name to a piece of code perhaps we shouldn't. The art of naming in programming is not the art of giving names but the art of deciding what to name.
We have power over the names that exist in our code using the opposite actions of inlining and extracting. When we extract a code fragment by assigning it to a variable we have to give it a name. And when we inline a piece of code we take away its name, by passing it directly into the next operation.
Deciding what code to inline can easily paralyse us with the amount of factors calculating into it. Is a function taking too many arguments? Is a pipeline of operations too long to be understandable? Is this piece of code reusable elsewhere? Does this piece of code require unit testing? Is this piece of code merely a layer of indirection? The list goes on.
We can structure our code by weighing these factors against each other, then try our hardest to find the best names for functions and variables we created in the process. But there's a better way. Explaining what the code is supposed to be doing to oneself or an audience reveals what parts of its operation are trivial to name. We then write our code to use only those trivial names.
To help us write code around certain names let's take a look at how some common refactors in our toolbox affect names. We can extract a value into a variable which allows us to name that variable. We can extract a function which allows us to name the function and its arguments. We can lift a function to a higher scope allowing us to name extra arguments of things the function previously read from the scope. We can invert any of these operations to make names disappear. The trick here is to put aside personal preferences one might have for these refactors and simply see them as different means towards the goal of bringing into existence trivial names and eliminating all others.
A result of this strategy can be that certain inlined chains of operations become too long to be easily understood. This might pressure us to locally compromise our naming standards by breaking up the chain into smaller operations with non-trivial names. I personally believe these long chains signify deeper problems that naming will not be able to address, but that is a topic for another post.