by Leon Rosenshein

Primitive Obsession and Boolean Blindness

George Boole brought us Boolean algebra. There’s tremendous benefit in using it. Boolean algegra is one of the foundations of computer science and factors into a lot of what we do as developers. But sometimes, it can also blind you to a deeper truth.

I’ve talked about primitive obsession before. It’s where you use a base type to represent a specific domain type. Like storing a URI as a string, It works, and its faster at first, but it’s also very limiting. Instead of building an object that understands itself, you build the functionality to use the primitive type as if it were the domain type. It works, but future you is going to be unhappy.

Boolean blindness is a specific kind of primitive obsession. That’s where you use a Boolean value to store the value of something that is really more nuanced than that. There are two common ways this happens.

One is where things don’t map neatly to True/False. Instead, you have some possible list of values and some of them would be considered True and others would be considered False. This can happen a lot in state machines, like bug databases. You often want to know if a particular entry is open, active, or closed. That entry, however, can have many states than that. You could have a Boolean for every possible state and some complex logic that keeps them all updated, at the same time, but that’s brittle and error-prone. A better choice might be to have a enum for the possible states and a way to determine if a given state IsOpen or IsClosed.

The other case is where there is a very clear definition of True/False, but there’s more data you want to store. In my Wikipedia entry (if I had one), there would be a birth date, but no date of death. I could have two variables, a Boolean called isDead and a Date called diedOn. The second would only be meaningful if the first were true. That works, but again, that’s very brittle. You need to make sure that diedOn is only used when isDead is True, and that any change to diedOn changes isDead appropriately. A better choice here would be some kind of nullable or optional date, diedOn. If diedOn has a value then I’m dead and the value is when I died. If it doesn’t I’m still alive. It might be wrong, but it can’t be inconsistent.1 It’s easy to imagine a much more complex class where isTrue is a complicated function of a bunch of internal state. Most languages won’t let you define the truthiness of a class, but you can imitate it by having a method on the class IsTrue() that handles that for you.

In other words, sometimes Boolean Blindness hides information by turning a multi-state thing into a two-state thing. In other cases you have the information and you just end up repeating yourself (and often getting out of sync). And sometimes that Boolean really is what you want. The trick is to actually make the choice knowingly, not by default or by mistake.

  1. There’s a whole different article around consistency vs correctness, but that’s something for the future. ↩︎