A Common Programmer Mistake: Dog is not the Opposite of Cat

True is the opposite of false. Up is the opposite of down. What is the opposite of dog?

If you replied “cat”, what exactly makes cats the opposite of dogs the same way up is the opposite of down?

I use this example to point out a common problem that software developers make with variable and parameter names. When there are two possible values for some variable or parameter, it is very common that it should be defined as a boolean type.

For example, a parameter might be called foobarEnabled and a True or False value is passed for it. This makes sense. The foobar is either enabled or disabled. “Not enabled” has a distinct and unambiguous opposite value, “disabled”. A boolean here makes perfect sense.

However, there is also a case when the two (and only two) possible values are not necessarily opposites. In this case, a boolean value is the wrong data type to use. On a recent web app I was working on, there is a form that has an “add foo” and “edit foo” mode, depending on whether the widget is adding a new foo or editing an existing foo (they use pretty much the same form fields, but the backend needs to know for technical reasons.)

To differentiate between them, the function that handles this form has an isAddMode parameter. If the form was submitted in Add mode, a True value is passed to this parameter. If the form was submitted in Edit mode, a False value is passed to this parameter. Knowing that “add” and “edit” are the only two values, this makes sense to the programmer writing this code. (But then again, programmers always think the code they themselves write makes sense.)

But from the perspective of another programmer who has to maintain this code later, this is the completely wrong name and data type for this parameter. Having “not add mode” does not instinctively convey “edit mode” the same way “not enabled” conveys “disabled”.

Dog is not the opposite of cat.

The correct name for a parameter like this would be something like “mode” or “addOrEditMode” depending on how verbose you want to be. The correct data type for a parameter like this is an enum type with two values for “add” and “edit”.
It may seem like a trivial detail, but making your code as readable as English is a key to having cleanly written code which is easy to understand and easy to debug.

(By the way, if you would like to know what the opposite of “cat” is, it’s “triceratops”.)

7 thoughts on “A Common Programmer Mistake: Dog is not the Opposite of Cat

  1. Here I thought I was the only one who thought this way. Making our code read like a story without having to become human compilers is something I have been stressing to my dev teams, both state side and offshore.

    Part of designing and developing code is being mindful of the future, for you may have to work on your own code and you don’t want to be that guy/gal who says, “What the heck was I smoking the day I wrote that code?!”.

  2. Entirely personal preference, but I’d much rather read

    if formSubmitMode == ‘add’:

    Than

    if isAddMode:

    It’s not that the second is complicated or hard to understand, but the first is much more obvious at first read.

  3. I understand your argument, and I can see merit in using an enum, instead. However, your premise is slightly flawed. If isAddMode is False, it doesn’t have to imply anything but the form is not in add mode. Since, the only alternative is edit mode, it’s in edit mode, but that doesn’t imply that edit is the opposite of add.

    That said, if there were a third mode, then isAddMode becomes insufficient to properly distinguish the mode of the form. At which point, something like an enum would need to be employed instead. So, you can criticize the developer for not building in extensibility from the start, but there’s really nothing wrong with the logic.

  4. It’s always possible to follow a suggestion and still write useless code. The concept “Dog is not the opposite of Cat” isn’t a theory of programming designed to make useless code impossible, it’s a simple rule to help people on the path to being able to see for themselves what good code looks like.

    The new programmer shouldn’t HAVE to figure out of Edit is the opposite of Add. The less mental gymnastics you have to do to read the code, the more room you have to understand the meaning of the code. It’s not a flag, it’s a mode. Some day there might be a delete mode or circle the world mode or format the user’s hard drive mode.

    Good post.

  5. One other thing I tend to do to make debugging easier for these sorts of mode situations is to always put in an error catch for unrecognized modes. One way I’ve seen to handle a two-way mode condition is to do if mode == add then … else …, assuming that if it doesn’t match the first x modes then it has to be the last possible mode. The problem with that kind of fallback condition is that a lot of times if somehow a new mode gets added and the old code isn’t updated, you’re now treating the new mode as whatever the old fallback mode happened to be. Instead I always explicitly match each mode and throw an exception in the else case (or at least fail an assertion if there really is a default fallback mode), so that those sorts of errors can be easily caught if they do crop up.

  6. I’ve been annoyed lately by the opposite problem: A varchar field has been used for five years and billions of rows with only two values, both of them six characters long. The code is littered with those two text strings, and I’m not sure it’s worth switching to a boolean, but I keep considering it.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>