The Solecistic Boolean

Stephen Young
Zumba Tech
Published in
4 min readAug 25, 2015

--

Solecism (n.) Erroneous or improper usage; absurdity.

I recently had an interesting debate with an internet acquaintance about the semantics of using a boolean as a return value in a function. The function under scrutiny was an event handler callback in an event bus system. The framework allows a user to stop an event from propagating by returning false:

this.$on('SomeEvent', data => {
// [...] Do some work with data
return false; // prevent propagation
});

If the handler did not return false the event would propagate to other handlers. The creator of the framework was contemplating whether broadcasted events should instead stop propagating by default unless a handler explicitly returns true; this would prevent components from unintentionally leaking their events to other components in large applications.

I’ve never liked this pattern. Assigning additional meaning to a boolean forces the developer to memorize an api — or worse, stop developing to go read the documentation. Booleans are (usually) not semantic.

The Classic Boolean Parameter

To better understand what I mean, let’s take a look at a more well-known anti-pattern: the boolean parameter. The following example highlights the underlying semantics issue.

this.save({ id : 5, text : 'awesome' }, true);

Here you can clearly reason that an object will be saved. But what does the second parameter do? Unless you have memorized the save method you’ll have to go look it up.

Usually an api like the one above is the result of iteration. The save method probably began its life accepting a single parameter: the object to save. Eventually there was a need to do something slightly different (e.g. an upsert operation), so a boolean was introduced. This is easy to develop but starts to become a nightmare to maintain in large applications. A better solution would be using an option object:

this.save({ id : 5, text : 'awesome' }, { upsert : true });

This is still using a boolean, but the object property key provides the calling code with semantics. You no longer need to look up or memorize the save method to understand what the code is doing.

But, Everyone Knows What False Means

Let’s think back to our event handler. I suggested to the project maintainer that returning a boolean is not semantic and that a function parameter callback could be used to propagate the events instead, something like this:

this.$on('SomeEvent', (data, propagate) => {
// [...] Do some work with data
propagate();
});

With this pattern, the event would only propagate when the user explicitly called the propagate function that was passed to the handler.

I’ve always known that return false means to stop propagating; it’s a standard used everywhere. If everyone knows what it means then it is semantic.

— bystander in response to my proposal (paraphrased, emphasis mine)

Well, that’s not really true (wink).

Knowing a thing does not make it explicit. The developer subjectively knows the boolean’s meaning because they are applying context and prior experience. A green developer would likely not recognize the pattern — and that is a key point. Semantic code can be taken at face value with little prior knowledge.

The Semantic Boolean

In other words: not all booleans are bad. Think of a boolean value as an answer to a particular question. If your code is asking a question that needs a yes-or-no answer, returning a boolean value is totally semantic. The classic example are “is*” methods:

if (this.isSemantic()) {
console.log('yup.');
}

There’s even a case for using boolean parameters — usually when executing a setter method. This line of code is semantic:

this.setEnabled(true);

Programs must be written for people to read, and only incidentally for machines to execute.

— Harold Abelson

Go Forth And Prosper

If you objectively consider a boolean value, it is clear that it has no further context beyond true or false. For the event handler above, I would argue that returning a string — e.g. “stop propagating” — would be a much more semantic pattern (albeit an ugly and brittle pattern, to say the least).

Always think about how and by whom code will be used in the future. Without a keen eye toward semantics the code is probably just slowing someone down.

Design for readability.

Even if you don’t intend anybody else to read your code, there’s still a very good chance that somebody will have to stare at your code and figure out what it does: That person is probably going to be you, twelve months from now.

— Raymond Chen

--

--

Stephen Young
Zumba Tech

Software Engineer, Gamer, Molecular Gastronomist