Five rules for coding with Booleans

opinion
May 20, 20256 mins
CareersDeveloperEngineer

Booleans may seem harmless, but using them can be fraught with peril. When you canโ€™t avoid them, follow these five rules.

A neon sign with the word TRUE in green and the word FALSE in red on a grunge background.
Credit: Wirestock Creators / Shutterstock

Booleans are deceptively simple. They look harmlessโ€”just true or false, right? What could possibly go wrong?ย But when you actually use them, they quickly become a minefield.ย 

After years of coding, I have learned to tread very lightly when dealing with this simple type.ย Now, maybe you like Booleans, but I think they should be avoided if possible, and if not, then very carefully and deliberately used.

I avoid Booleans because they hurt my headโ€”all of those bad names, negations, greater thans, and less thans strung together. And donโ€™t even try to tell me that you donโ€™t string them together in ways that turn my brain into a pretzel because you do.ย 

But they are an important part of the world of programming, so we have to deal with them.ย Here are five rules that I use when coding with Booleans:

  1. Stay positive
  2. Put positive first
  3. No complex expressions
  4. Say no to Boolean parameters
  5. Booleans are a trap for future complexity

Stay positive

When dealing with Boolean variables, I try to always keep their names positive, meaning that things are working and happening when the variable is True. So I prefer expressions like


if UserIsAuthorized {
  // Do something
}

rather than


if !UserIsNotAuthorized {
  // Do something
}

The former is much more readable and easier to reason about.ย Having to deal with double negatives hurts the brain. Double negatives are two things to think about instead of one.

Put positive first

In the spirit of staying positive, if you must use an if... else construct, put the positive clause first. Our brains like it when we follow the happy path, so putting the negative clause first can be jarring. In other words, donโ€™t do this:


if not Authorized {
  // bad stuff
} else {
  // good stuff
}

Instead put the positive clause first:


if Authorized {
  // Things are okay
} else {
  // Go away!!
}

This is easier to read and makes it so you donโ€™t have to process the not.ย ย 

No complex expressions

Explaining variables are drastically underused. And I get itโ€”we want to move quickly. But it is always worthwhile to stop and write things outโ€”to โ€œshow your work,โ€ as your math teacher used to say.ย I follow the rule that says only use && and || between named variables, never raw expressions.

I see this kind of thing all the time:


if (user.age > 18 && user.isActive && !user.isBanned && user.subscriptionLevel >= 2) {
  grantAccess();
}

Instead, you should consider the poor person who is going to have to read that monstrosity and write it out like this instead:


const isAdult = user.age > 18;
const hasAccess = !user.isBanned;
const isActive = user.isActive;
const isSubscriber = user.subscriptionLevel >= 2;

const canAccess = isAdult && hasAccess && isActive && isSubscriber;

if (canAccess) {
  grantAccess();
}

This is eminently readable and transparent in what it is doing and expecting. And donโ€™t be afraid to make the explaining variables blatantly clear.ย I doubt anyone will complain about


const userHasJumpedThroughAllTheRequiredHoops = true;

I know it is more typing, but clarity is vastly more valuable than saving a few keystrokes.ย Plus, those explaining variables are great candidates for unit tests. They also make logging and debugging a lot easier.

Say no to Boolean parameters

Nothing generates more โ€œWhat the heck is going on here?โ€ comments per minute than Boolean parameters.ย Take this gem:


saveUser(user, true, false); // ...the heck does this even mean?

It looks fine when you write the function, because the parameters are named there. But when you have to call it, a maintainer has to hunt down the function declaration just to understand whatโ€™s being passed.ย 

Instead, how about avoiding Booleans altogether and declare a descriptive enum type for the parameters that explains what is going on?


enum WelcomeEmailOption {
  Send,
  DoNotSend,
}

enum VerificationStatus {
  Verified,
  Unverified,
}

And then your function can look like this:


function saveUser(
  user: User,
  emailOption: WelcomeEmailOption,
  verificationStatus: VerificationStatus
): void {
  if (emailOption === WelcomeEmailOption.Send) {
    sendEmail(user.email, 'Welcome!');
  }
  if (verificationStatus === VerificationStatus.Verified) {
    user.verified = true;
  }
  // save user to database...
}

And you can call it like this:


saveUser(newUser, WelcomeEmailOption.Send, VerificationStatus.Unverified); 

Isnโ€™t that a lot easier on your brain?ย That call reads like documentation. Itโ€™s clear and to the point, and the maintainer can see immediately what the call does and what the parameters mean.ย 

Booleans are a trap for future complexity

An advantage of enums is they are expandable.ย Imagine you haveย a food and beverage system that has small and large sized drinks.ย You might end up with


var IsSmallDrink: boolean;

And you build your system around that Boolean variable, even having Boolean fields in the database for that information. But then the boss comes along and says, โ€œHey, we are going to start selling medium drinks!โ€

Uh oh, this is going to be a major change. Suddenly, a simple Boolean has become a liability. But if you had avoided Booleans and started with


enum DrinkSize {
  Small,
  Large
}

Then adding another drink size becomes much easier.

Look, Booleans are powerful and simple.ย Iโ€™m old enough to remember when languages didnโ€™t even have Boolean types. We had to simulate them with integers:


10 LET FLAG = 0
20 IF FLAG = 1 THEN PRINT "YOU WILL NEVER SEE THIS"
30 LET FLAG = 1
40 IF FLAG = 1 THEN PRINT "NOW IT PRINTS"
50 END

So I understand their appeal.ย But using Booleans ends up being fraught with peril.ย Are there exceptions?ย Sure, there are simple cases where things actually are and always will be either true or falseโ€”like isLoading. But if you are in a hurry, or you let your guard down, or maybe you feel a bit lazy, you can easily fall into the trap of writing convoluted, hard-to-reason-about code.ย So tread lightly and carefully before using a Boolean variable.

Nick Hodges

Nick has a BA in classical languages from Carleton College and an MS in information technology management from the Naval Postgraduate School. In his career, he has been a busboy, a cook, a caddie, a telemarketer (for which he apologizes), an office manager, a high school teacher, a naval intelligence officer, a software developer, a product manager, and a software development manager. In addition, he is a former Delphi Product Manager and Delphi R&D Team Manager and the author of Coding in Delphi. He is a passionate Minnesota sports fanโ€”especially the Timberwolvesโ€”as he grew up and went to college in the Land of 10,000 Lakes. He currently lives in West Chester, PA.

More from this author