Fuzzy Words in Programming
The hardest problem in programming is not proving correctness, but naming things. Frequently, I find myself looking at a new codebase, or a section of a larger codebase I haven’t been exposed to so far, and I have problems determining what this code is supposed to do.
Sometimes this is due to 400-line-functions that should have had their different code paths split up into separate functions ages ago, but other times, the code is well-structured and I’m familiar with the domains terminology, but the naming of the variables and functionsand classes still actively hinders understanding. Why is that? How can this be?
Class of word
One thing I’ve seen is that identifier names don’t follow the grammar of a
sentence or don’t use the proper class of word. If a method triggers an actual
process, an action as the user would understand it, it should be a verb.
setFoo:
applies a change. If a method named commandProcessor
actually runs a loop that processes commands, it should be renamed
runCommandProcessingLoop
instead. That way, when I read it somewhere,
even if I havent read its contents yet, I have a general idea what it does.
If it doesnt contain a verb, Ill have to make up my own. What could it be?
createCommandProcessor
? resetCommandProcessor
?
Of course, there are fuzzy spots. If NSViewController
s view
method implicitly loads and creates the view, shouldnt it be called
loadView
instead? Or is this an implementation detail that I can leave
out? In general, I tend to count caches and lazy-loading that happens as needed
as implementation details. So your property does not have to be named as a verb.
Cases and modifiers
Another thing that I see a lot, particularly in codebases that have a lot of
non-native English speakers working on them, are problems with cases. This can
take the shape of reversed word-order that has the defining word of a compound
at the wrong end, like ListChannel
instead of ChannelList
.
This can be very unfortunate, as in English, many verbs are identical to their
nouns, and only differ in their position in the sentence. So when I see
ListChannel
I don’t just think this is a single channel that somehow
contains or presents a list, but rather I might read it as a verb. When someone
declares a variable of this type, my interpretation, in order of likelihood is
therefore:
- A block or functor type that somehow lists channels.
- A channel that somehow lists something.
- A mis-named list of channels.
Where the right one, in our example, is the 3rd and least likely choice.
Another common mistake is excessive use of plurals, like
MyChannelsList
. This may look harmless at first, but can in some cases
lead to ambiguity. E.g. if your project convention is to name typed arrays as
the plural of your element type, this would be a list of Channels
objects, which in turn are lists of Channel
objects. Now, ignoring the
(lack of) wisdom of having a one-character difference in names, excessive
plurals like that make me mistrust the code and force me to check whether there
is a reason for this extraneous plural or not.
Fuzzy words
The third class of bad names that I see in projects are fuzzy words. The most common case are class and file names that don’t have a clearly delineated meaning and therefore attract functionality like one of those magnetic cranes in a junk yard.
Utilities.h
NetworkExtras
MYOtherDebugMenuSection
StringExtensions
NSURL+Helpers.h
NSDictionary+MyApplication.h
I’m sure you can come up with more examples, but they all have one thing in common: They are so generic that almost no method or function is off-topic for this file. And when you’re actually searching for a particular method or function in a foreign codebase, any of these files is probably a good candidate.
While Utilities.h
is obviously a catch-all into which everyone can dump
whatever they want when they are too lazy to add a new file to a project just
for this one function, or want to avoid having to merge project files if
someone else also just added another file to the project, the others are less
obvious, but just as magnetic:
The network is a big place, with many layers. Is this just a wrapper to convert
certain data types before theyre sent over a socket? Are these actual protocol
implementations? URL string-formatting functions? So much could be valid for a
class named NetworkExtras
.
I worked on one project that contained a debug menu that scrolled for 3 screens, and where none of the menu items could be re-used in other projects easily because all the code for them was in the application delegate, causing that to need a recompile every time one of them changed.
So for the next project, I created a MYDebugMenuSection
class whose
+load
method adds it to a list which is then used to build the debug
menu. Each of these classes is one submenu. So I now have a generic
MYViewsDebugMenuSection
that turns on/off lots of view-related things
(like drawing their frames, flashing updates etc.) or logs the view hierarchy.
To every new project, we can just add that header and source file, and get the
same debug features we have in every other app.
Then someone found that too onerous, and created an Other submenu, and shortly, another developer added another bunch of items to this menu instead of creating their own section for their submodule. All we gained was that you now had to navigate to a submenu before you were forced to scroll through your 3 screens full of items. So I split them, and renamed them, to avoid the magnetism of the fuzzy Other.
StringExtensions
? Same problem. There are lots of things you do with strings.
Name it StringURLFormattingExtensions
, or be prepared to have to split the file
every few weeks. Same with NSURL+Helpers
.
Magnetism
Some of you may not believe me. And I don’t blame you, its easy to overshoot the target. To create headers that are too concrete and really only contain one function. I agree, thats bad. Avoiding that requires common sense, too. But if you don’t believe that crap is magnetic, go to an underpass that is not publicly visible from the outside and has a big empty flat wall that has been freshly painted. Visit it regularly.
At first, itll be virginally white. Then, someone will paint a tag on it, or stick a sticker on it. Then itll stay like that for a while. Then the next person will come along, and shell think: Hey, nobody removed the tag. Lets put mine on there as well! And then therell be more and more tags, until finally someone will slap a gorgeous graffiti over it. And then someone else will add another one, and a few taggers will tag in empty spots on the graffiti
This even works with advertisements. Here in Munich, under the Heimeranplatz train overpass, there was an insurance advertisement that, as part of its picture, contained a few scrawls that, blown up to billboard size, looked just like tags. Within a month, the billboard had accumulated another dozen or two tags on what was obviously a derelict billboard.
It works with garbage: One person stuffs a paper cup in a hole in the wall, other people throw their trash there as well.
It works with code. Send the bin man round every few weeks. Youll love your codes fresh smell.