Booleans
Strictly speaking, LFE has no Boolean type, just like Erlang. Instead, the atoms
true
and false
are treated as Booleans
lfe> (== 42 "the question")
false
lfe> (== 42 42)
true
lfe> (> 1 2)
false
lfe> (< 1 2)
true
Operators
The standard logical operators are available to LFE Booleans:
lfe> (not 'true)
false
lfe> (not 'false)
true
lfe> (and 'true 'false)
false
lfe> (or 'true 'false)
true
lfe> (and 'true 'true 'true)
true
lfe> (and 'true 'true 'false)
false
lfe> (or 'false 'false 'false)
false
lfe> (or 'false 'false 'true)
true
lfe> (xor 'true 'true)
false
lfe> (xor 'true 'false)
true
lfe> (xor 'false 'false)
false
lfe> (xor 'false 'true)
true
With the and
and or
Boolean oprators, every argument is evaluated. To
accomodate situations where complex and possible expensive logical expressions
comprise the arguments to Boolean operators, short-circuit versions of these
functions are also provided:
- with
andalso
, returns as soon as the first'false
is encountered; - with
orelse
, returns as soon as the first'true
is encountered.
To demonstrate this, we'll define a boolean function that prints to
standard out
when it is evaluated:
(defun hey (x)
(io:format "Made it here!~n") x)
Short-circuit demonstration of andalso
:
lfe> (andalso 'true 'true 'false (hey 'true))
false
lfe> (andalso 'false 'true 'true (hey 'true))
false
lfe> (andalso 'true 'true 'true (hey 'true))
Made it here!
true
Short-circuit demonstration of orelse
:
lfe> (orelse 'false 'false 'true (hey 'true))
true
lfe> (orelse 'true 'false 'false (hey 'true))
true
lfe> (orelse 'false 'false 'false (hey 'true))
Made it here!
true
Predicates
To test if a value is a Boolean, we will first include some code:
lfe> (include-lib "lfe/include/cl.lfe")
That adds Common Lisp inspired functions and macros to our REPL session.
lfe> (booleanp 'true)
true
lfe> (booleanp 'false)
true
lfe> (booleanp 'arthur)
false
lfe> (booleanp 42)
false
If the atom in question has been used in a function name definition:
If you prefer the Clojure-style of predicates:
lfe> (include-lib "lfe/include/clj.lfe")
lfe> (boolean? 'true)
true
lfe> (boolean? 'false)
true
lfe> (boolean? 'arthur)
false
Of course there is always the Erlang predicate, usable without having to do any includes:
lfe> (is_boolean 'true)
true
lfe> (is_boolean 'false)
true
lfe> (is_boolean 'arthur)
false
Note that, since LFE Booleans are also atoms, these are valid as well:
lfe> (atomp 'true)
true
lfe> (atom? 'false)
true
lfe> (is_atom 'true)
true