Name Boolean Constants Based on What They Conceptually Represent [VD10]
Tip VD10
Boolean constants are best named for what they conceptually represent, rather than their literal values. Prefer naming boolean constants just like any other constant.
Constants should generally be named based on what they conceptually represent, rather than their literal values. This can sometimes present a tension when thinking about good boolean constant names - typical boolean naming advice may seem to contradict typical constant naming advice. Reconciling the two into a consistent convention that can be followed is important for readability and correctness of code over the long term.
Walking Through an Example of Code That Can Operate in Multiple “Modes”
Consider the example of some code that can operate in multiple “modes”:
Considerations in Naming the Constant
The MODE constant in the above is intentionally left vague for now because we need to explore the considerations involved in naming it:
Considering typical boolean names: First off, note that this boolean isn’t named with a name that typically implies “true” or “false.” It would be possible to create a more boolean name like
IN_PERFORMANCE_MODE,DO_NOT_USE_PERFORMANCE_MODE,USE_QUALITY_MODEor , but those could look a bit odd:IN_PERFORMANCE_MODEwould be a name that corresponds to the “conceptual” name of the parameter (tweaked slightly to make it more obviously boolean compared to justPERFORMANCE_MODE). But having it assigned to a value offalse, which means not performance mode, is very misleading both for the meaning of this constant name itself and in usage code.DO_NOT_USE_PERFORMANCE_MODEwould be negative and assigned a negativefalsevalue, and negative booleans (particularly if double/multiple negatives are involved) tend to be harder to comprehend.USE_QUALITY_MODEis positive but would be assigned a negativefalsevalue in this example.
Considering where the boolean is used: This boolean constant is used in places - notably the
DoSomething(MODE)line. Readability of this usage code is important - you want readers of places where the boolean constant is used to correctly interpret the code. When they read this line, it better do what it actually says it does. At a macro level for most programs, this is probably the most important consideration. WouldDoSomething(IN_PERFORMANCE_MODE),DoSomething(DO_NOT_USE_PERFORMANCE_MODE), orDoSomething(USE_QUALITY_MODE)better communicate the actual behavior to readers?DoSomething(IN_PERFORMANCE_MODE)is very inaccurate in communicating the behavior - the opposite is what would actually happen.DoSomething(DO_NOT_USE_PERFORMANCE_MODE)is better in that it communicates some information about the behavior of the program, but it may not be as much as could be communicated.DoSomething(USE_QUALITY_MODE)better communicates more information about what the program would actually do.
Arriving at a Conclusion
Taking the above considerations together:
The
DoSomething()function parameter ofperformance_modecould be updated to be more obviously boolean likein_performance_modefor additional clarity.A boolean constant name like
QUALITY_MODEseems like a reasonable choice to make sure usage code likeDoSomething(QUALITY_MODE)would better communicate what actually happens.For making the boolean constant name also read more like a boolean, it could be tweaked to
USE_QUALITY_MODE.
That would result in final code that looks like:
This does mean that the constexpr bool USE_QUALITY_MODE = false line looks a bit odd - a negative false value assigned to a positive boolean name? In isolation, this can be a bit confusing since the meaning of USE_QUALITY_MODE is “yes, use quality mode”, but the value on this line of false at a first pass would suggest “not quality mode.” However, in the grand scheme of things, this line is the least important out of all lines involved here - the other lines involving usage code and the actual parameter are more important. And the “discrepancy” on this line is also centralized in one place, whereas function calls that might use this constant might occur in many places. So in some sense, it’s okay for this line to be “less good” since it brings benefits in other places.
A Potentially Better Solution with an Enum
It’s also worth noting that what is trying to be represented with this constant isn’t primarily a boolean true/false value. What is trying to be represented is a domain concept of some “operating mode.” The boolean data type is an implementation choice based on the constructs provided by a given programming language to express an idea, and different programming languages may provide different constructs that make things easier/harder to represent in different ways. Whatever constant name is used here is an abstraction. Once you’ve determined available/useful abstractions, your trick as a programmer is to try and choose the best implementation option available to you in your given programming language.
In this case, the naming difficulties are a warning sign that a boolean may not be the most appropriate abstraction. Many programming languages provide the ability to define enumerated types that could be better suited for this kind of problem:
Using a slightly more powerful abstraction side-steps many of the naming problems discussed in this section.
Enums are slightly more complex than booleans, even if not by much - there’s an additional data type to define/maintain, and enums are often used in switch statements that would require maintenance updates as available enum values are changed. That extra complexity may not be worth it in all scenarios, but it enums can be a way to resolve these kinds of challenges in many instances.