# Equality of booleans in Emacs

There is a fun story about booleans in Emacs Lisp - there are no booleans in Emacs Lisp. Sort of. Because we have a symbol `nil`

, which means an empty list. You can write it as `nil`

or `()`

- they both stand for the same object, the symbol `nil`

.

`eq nil ()) ; => t (`

Since LISP is all about list processing, empty list is something very `false`

. So `false`

that we don’t have special symbol for `false`

values, as empty list serves this purpose well.

Everything that is not an empty list has a meaning of `true`

. However, there is a symbol `t`

which is the preferred way to represent the truth value `true`

.

So `nil`

and `t`

are considered canonical boolean values. There is a function `booleanp`

that returns `t`

if the argument is a canonical boolean value and `nil`

otherwise.

The fun begins when you need to check if two boolean values are equal. Since non-nil (or not an empty list) can mean many different things (like `"Emacs is the only true editor"`

) you can’t just do regular equality check.

`equal t "Emacs is the only true editor") ; => nil (`

There are, however, several tricks to get it working. The most obvious solution is to convert value to a canonical boolean value.

# if/when

We can directly use `if`

function.

```
if "Some truth" t nil) ; => t
(if 42 t nil) ; => t
(if t t nil) ; => t
(if nil t nil) ; => nil
(
let ((a t)
("Emacs is the only true editor"))
(b equal (if a t nil) (if b t nil))) ; => t
(
defun boolean-eq (a b)
(equal (if a t nil)
(if b t nil)))
(
let ((a t)
("Emacs is the only true editor"))
(b ; => t (boolean-eq a b))
```

Directly using `if`

is a little bit cumbersome, but when we hide it inside of a helper function it’s not that bad, actually.

The same result can be achieved by using `when`

.

```
when "Some truth" t) ; => t
(when 42 t) ; => t
(when t t) ; => t
(when nil t) ; => nil
(
let ((a t)
("Emacs is the only true editor"))
(b equal (when a t) (when b t))) ; => t
(
defun boolean-eq (a b)
(equal (when a t)
(when b t)))
(
let ((a t)
("Emacs is the only true editor"))
(b ; => t (boolean-eq a b))
```

# not

There is another function we can use - `not`

, which returns `t`

if the argument is `nil`

, and returns `nil`

otherwise. Yes, it negates the value, but the result is one of the canonical booleans, so we are good.

Since *a* ≡ *b* is equivalent to ¬*a* ≡ ¬*b*, we can just compare negated values.

a |
b |
¬a |
¬b |
a ≡ b |
¬a ≡ ¬b |
---|---|---|---|---|---|

0 | 0 | 1 | 1 | 1 | 1 |

0 | 1 | 1 | 0 | 0 | 0 |

1 | 0 | 0 | 1 | 0 | 0 |

1 | 1 | 0 | 0 | 1 | 1 |

```
not "Some truth") ; => nil
(not 42) ; => nil
(not t) ; => nil
(not nil) ; => t
(
let ((a t)
("Emacs is the only true editor"))
(b equal (not a) (not b))) ; => t
(
defun boolean-eq (a b)
(equal (not a) (not b)))
(
let ((a t)
("Emacs is the only true editor"))
(b ; => t (boolean-eq a b))
```

This one looks a little bit better when used without a helper function, at least in my opinion.

# xor/or/and

Sometimes you want to do something when two ‘boolean’ values are not equal.

```
let ((a nil)
("Emacs is the only true editor"))
(b unless (equal (not a) (not b))
("Some real work begins"))) ; => Some real work begins (message
```

For such situations, there is a `xor`

function, which returns `nil`

when both arguments are equal in the canonical boolean form and `t`

otherwise.

```
nil nil) ; => nil
(xor nil t) ; => t
(xor t nil) ; => t
(xor t t) ; => nil
(xor
"Some truth" nil) ; => t
(xor "Some truth" t) ; => nil
(xor
42 nil) ; => t
(xor 42 t) ; => nil
(xor
let ((a nil)
("Emacs is the only true editor"))
(b when (xor a b)
("Some real work begins"))) ; => Some real work begins (message
```

Other functions (like `or`

, `and`

) also convert values to canonical boolean values. So you can keep it in mind.

# Epilogue

The sole purpose of this post is fun. If you didn’t get your portion of fun, then it’s not funny at all. Please fix it somehow.