How can I make a call with a boolean clearer?

by Mario Garcia   Last Updated May 16, 2018 14:05 PM

I usually run into this question, and I never know the best answer.

Say I have a function like this

UpdateRow(var item, bool externalCall);

and in my controller, that value for externalCall will always be TRUE. What is the best way to call this function? I usually write

UpdateRow(item, true);

But I ask my self, should I declare a boolean, just to indicate what that 'true' value stands for? You can know that by looking the declaration of the function, but it's obviously faster and clearer if you just saw something like

bool externalCall = true;
UpdateRow(item, externalCall);

Thanks for your opinions.

PD: Not sure if this question really fits here, if it doesn't, where could I get more info about this?

Tags : boolean const


Answers 4


The correct solution is to do what you suggest, but package it into a mini-facade:

void updateRowExternally() {
  bool externalCall = true;
  UpdateRow(item, externalCall);
}

Readability trumps micro-optimization. You can afford the extra function call, certainly better than you can afford the developer effort of having to look up the semantics of the Boolean flag even once.

Kilian Foth
Kilian Foth
May 16, 2018 13:12 PM

There is no perfect solution, but many possible alternatives to choose from.

  • Use distinct functions for your public interface, with better names. This is very readable, but leads to a lot of boilerplate for you, who is writing these functions. It also can't deal well with combinatorial explosion when there are multiple boolean arguments. A significant drawback is that clients can't set this value dynamically, but must use if/else to call the correct function.

  • Use named arguments, if available in your language. This works very well and has no particular drawbacks.

    Your suggestion to use a separate variable is one way to simulate named arguments, but does not have the associated safety benefits (there's no guarantee that you used the correct variable name for that argument).

  • Use an enum. The problem with booleans is that they are called "true" and "false". So, instead introduce a type with better names (e.g. enum CallType { INTERNAL, EXTERNAL }). As an added benefit, this increases the type safety of your program (if your language implements enums as distinct types). The drawback of enums is that they add a type to your publicly visible API. For purely internal functions, this doesn't matter and enums have no significant drawbacks.

    In languages without enums, short strings are sometimes used instead. This works, and may even be better than booleans, but is very susceptible to typos. The function should then immediately assert that the argument matches a set of possible values.

amon
amon
May 16, 2018 13:28 PM

  1. You can 'name' your bools. Below is an example for an OO language (where it can be expressed in the class providing UpdateRow()), however the concept itself can be applied in any language:

    class Table
    {
    public:
        static const bool WithExternalCall = true;
        static const bool WithoutExternalCall = false;
    

    and in the call site:

    UpdateRow(item, Table::WithExternalCall);
    
  2. I believe Item #1 is better but it doesn't force the user use new variables when using the function. If type safety is important for you, you can create an enum type and make UpdateRow() accept this instead of a bool:

    UpdateRow(var item, ExternalCallAvailability ec);

  3. You can modify the name of the function somehow that it reflects the meaning of the bool parameter better. Not very sure but maybe:

    UpdateRowWithExternalCall(var item, bool externalCall)

simurg
simurg
May 16, 2018 13:32 PM

Say I have a function like UpdateRow(var item, bool externalCall);

Why do you have a function like this?

Under what circumstances would you call it with the externalCall argument set to different values?

If one is from, say, an external, client application and the other is within the same program (i.e. different code modules), then I'd argue that you should have two different methods, one for each case, possibly even defined on distinct Interfaces.

If, however, you were making the call based on some datum taken from an non-program source (say, a configuration file or database read), then the Boolean-passing method would make more sense.

Phill  W.
Phill W.
May 16, 2018 13:51 PM

Related Questions



Const C++ DRY Strategies

Updated July 16, 2015 19:02 PM



Defining static constants

Updated June 23, 2015 01:02 AM