DEV Community

Cover image for Boolean flags are sad little enums
András Tóth
András Tóth

Posted on

Boolean flags are sad little enums

I was thinking today that when I was a mid experience level engineer I have found a couple of problems where I could finally do something very smart and use 3-state logic instead of the classic true-false one.

I jumped in excitedly only to lose it when I realized "Wait, doesn't this make instead a good enum?". And then I went with a good ol' enum and all was well.

And now I am thinking again: wouldn't it make sense to replace as much as boolean flags with enums instead (or at least used named parameters).

See this example:

jsonb_set(data, '{user, role}', {
  id: 'supervisor',
  title: 'Chat group supervisor',
}, false);
Enter fullscreen mode Exit fullscreen mode

When you are writing this, you still remember what was the false for the last parameter.
I give you a weak and if you are not using this jsonb_set function frequently you will have no memory of it.

We then waste time on things that could have been very clear.

Option 1: use enum

enum JsonbSetOption {
  CreateIfDoesNotExist,
  ThrowErrorIfDoesNotExist
}

jsonb_set(data, '{user, role}', {
  id: 'supervisor',
  title: 'Chat group supervisor',
}, JsonbSetOption.ThrowErrorIfDoesNotExist);
Enter fullscreen mode Exit fullscreen mode

Basically anybody will know what this will do.

Option 2: passing named parameters

jsonb_set(data, '{user, role}', {
  id: 'supervisor',
  title: 'Chat group supervisor',
}, { throwErrorIfDoesNotExist: true });
Enter fullscreen mode Exit fullscreen mode

Option 3: split it into two functions

jsonb_set_throw_on_update_path_missing(
  data, 
  '{user, role}',
  {
    id: 'supervisor',
    title: 'Chat group supervisor',
  }
);
Enter fullscreen mode Exit fullscreen mode

It is up to you whichever you choose. Please don't just use random flags or else...

receiveSalary(you, false, true, true, false, null);
Enter fullscreen mode Exit fullscreen mode

Top comments (6)

Collapse
 
webbureaucrat profile image
webbureaucrat

I agree, and I would take it a step further--if you're passing flags, you should ask yourself if what you really need is a separate function. Like, consider:

jsonb_set_or_create(data, '{user, role}', {
  id: 'supervisor',
  title: 'Chat group supervisor',
})

jsonb_set_or_throw(data, '{user, role}', {
  id: 'supervisor',
  title: 'Chat group supervisor',
})
Enter fullscreen mode Exit fullscreen mode

There are times when passing flags or enums makes sense, but usually I think this is the better option because it results in less nesting inside the function (no switches or if/thens) and a little more intuitive to read the calling code (although readability is largely subjective).

Collapse
 
hakanai profile image
Hakanai

I'd definitely go for a separate function. I'd reserve enums (or possibly better, strategy objects?) for the case where there is more than option and I don't want to explode the API to N×M functions.

Collapse
 
nricks profile image
nricks

The strategy pattern where your flags/enums are actual representations themselves of the behaviour you want to achieve is much nicer and cleaner from a declarative standpoint.

Always keeping in mind the common sense boundary of over engineering.

Thread Thread
 
webbureaucrat profile image
webbureaucrat

The problem with saying that enums are more declarative than separate function definitions is that that's really only true if you're thinking of functions as imperatives, but functions themselves are also values and can be used just as declaratively as enums, but using functions over enums better encapsulates meaning by tying the representation with the definition.

OO patterns like that are mostly an attempt to make imperative languages a little bit less imperative, but they aren't inherently better than just doing things in a functional way.

Thread Thread
 
nricks profile image
nricks

much sorry I was in a hurry I meant to type:
"where your flags/enums are functions and actual representations themselves of the behaviour"

:D

Collapse
 
latobibor profile image
András Tóth

Fun fact this example was taken straight out of Postgres and indeed the flag is there, I did not make it up.
Your function names are very short and descriptive, I like them a lot! Thanks for your comment!