Jonathan Boccara's blog

Passing Booleans to an Interface in an Expressive Way

Published May 4, 2018 - 14 Comments

Daily C++

In order to allow a function to behave in several different way, and to allow its caller to choose amongst these behaviours, we have several tools at our disposal. Plenty, actually.

There are various sorts of polymorphisms embedded in the language such as virtual functions and templates. And we’ve also seen that a caller can specify the desired behaviour explicitly at call site. We’ve seen how to accomplish this by using tag dispatching, and also how to choose between enums and tag dispatching depending on your need.

I now want to top it off with a really simple technique, that will cost you almost nothing, but one that will make your code much more expressive. And even if it’s not rocket science I’m sharing this with you today because I’ve seen many a piece of code that could have benefited from it.

Passing a boolean to an interface

We’ve seen when passing an enum can be useful to elect a behaviour. Now there is a special case where an enum is not the best option: for on-or-off behaviours. In such cases, the natural representation is a boolean.

To illustrate, consider this constructor that creates a goblin. All goblins look alike, except for one thing: they can either wear a hat, or walk along bareheaded. And all goblins have the same goblin hat. (In fact, I’m no expert on goblins, if you work in the game industry and spend a lot of time working on goblins, please don’t be offended at this extreme simplification of goblins, it is just for the sake of the example).

class Goblin
{
public:
    explicit Goblin(bool wearsAHat);
    // ...
};

boolean flags

Given the domain rules, this interface looks reasonable. But it leads to an unclear call site:

Goblin bill(true);

This code creates Bill, a goblin that wears a hat. But that is not what this code says. It says that Bill has some attribute that is true. This is unclear. This code forces the reader to maintain a mapping in their head, that associates true to the fact of wearing a hat, and false to the fact of not wearing a hat.

This becomes even worse when there are several booleans passed to a function, with code resembling:

f(true, false, true); // ???

There is a very simple way out of this: giving names to the booleans:

class Goblin
{
public:
    static const bool WithAHat = true;
    static const bool WithoutAHat = false;

    explicit Goblin(bool wearsAHat){}
    
    // ...
};

The resulting call site then looks like this:

Goblin bill(Goblin::WithAHat);

It’s a bit of a shame to see the name of the class Goblin repeated two times. You could define the booleans just outside the class, this way:

const bool WithAHat = true;
const bool WithoutAHat = false;

class Goblin
{
public:
    explicit Goblin(bool wearsAHat);
    
    // ...
};

Goblin bill(WithAHat);

The call site is more direct, but the interface shows a bit less clearly that the constructor is expected to use the booleans, since they’re not longer immediately next to it.

This is still a boolean

There is an advantage of using a named boolean over an enum here. Since the fact of wearing a hat is an on-or-off thing, it’s natural to represent it as a boolean. A practical consequence is that there could be other functions that represent this info as a boolean. For instance, if users can describe what they want for their goblin, with a GoblinUserInput data, that can be read this way:

bool wearsAHat(GoblinUserInput);

This natural interface remains compatible with our class:

Goblin bill(wearsAHat(userInput));

Using an enum in the constructor instead of a boolean would have either led to a more cumbersome interface for the wearsAHat function if it had returned an enum (because returning a bool is the natural thing to do here), or forced a translation from the bool returned to the enum passed.

Should we name all booleans? false.

If you’re now convinced that booleans in an interface are better off with a name, you may wonder if there are exceptions to this guideline. And there are. Indeed, consider the following setter, that either puts a hat on the goblin or takes it off:

class Goblin
{
public:
    explicit Goblin(bool wearsAHat);
    void wearAHat(bool wearsAHat);
    // ...
};

The client code can call this setter the following way, to take Bill the Goblin’s hat off:

bill.wearAHat(false);

There is no need to give a name to the boolean here, because the setter already carries the information that it’s about wearing a hat.

To get to expressive code we need to display just the right amount of information. Nonce is not enough, Once is good enough, Twice enough is enough.

Related articles:

Don't want to miss out ? Follow:   twitterlinkedinrss
Share this post!Facebooktwitterlinkedin

Comments are closed