Back to Blog List

Not All Unicorns Have Horns

Published | 3 min read

A bit of Context

In my work, there’s this Permissions / Role module where user can set certain roles, grant permissions, etc. For better UX, we arrange these permissions into groups / modules, each group has its related set of permissions. Each permission has its own checkbox and the same goes for each permission group, if user checks, it selects all its own permissions, and vice versa.

All of this has been working fine untill one day we noticed that in the initial state, some gpermission groups were checked by default, it also happened that those groups had no permissions under. With quick look, the backend actually returns some permissions groups with empty permissions list.

For me that was a bit strange. I said to myself: The permissions list is empty, so isn’t the permission group supposed to be unchecked?. So I took a look at the code to see what’s happening, I found that we do this to check if all the permissions are checked (To check the permission group based on them or not):

const isAllPermissionsSelected = (group.permissions || []).every((p) => selectedPermissionsIds.value.includes(p.id));

For the first glance this seems fine, right? Short answer: No! It turns out that every() array method returns true if the array is empty! I was puzzeled and rushed to MDN’s Array.prototype.every() to find what am I missing here? Is it another Javascript shenanigans? I read until I hit this line:

every acts like the “for all” quantifier in mathematics. In particular, for an empty array, it returns true. (It is vacuously true that all elements of the empty set satisfy any given condition.)

Vacuous Truth

As someone who comes from a medical background, I was a bit perplexed. A “for all” quantifier? vacuously true? So I got a little bit curious so I followed this link that MDN provided: Vacuous truth. Feel free to read as it’s a very interesting to fathom. But anyhow, in short, Vacuous truth is a concept from logic where a statement of the form: “All X have property P” is considered true when there are no X at all.

It might feel wrong at first, but it’s logically consistent. A classic example to fathom this is The Unicorn Example. (Thus the name of this post). Think of the statement “All unicorns have horns.”, since unicorns don’t really exist, there is no counterexample (no unicorn without a horn). Because nothing violates the rule, the statement is considered true by default. That’s vacuous truth in action.

Anyhow, knowing this, the solution to our issue was pretty intuitive, just guard eagainst the empty array. But I believe understanding this concept is important in case I met a similar problem in the future.

Worth mentioning: Among other array methods, some() returns false if the array is empty.

Knowing this, I wanted to take this a bit further so I searched about other “vacous-like” behavior that I can find in Javascript, though every() is the only official JS example I can find on MDN, I came across differet cases that are worthy to be mentioned. The one that made me stop at is the fact that scheme validation libraries (e.g. Yup, Zod), if schema has no rules or object has no fields, validation passes.

Anyhow, I highly suggest checking out other examples that could go along the pattern, but in short, a general rule of thumb: Logically, any pattern asserting “all/none satisfy something” over an empty set is a vacuous truth.