## 17. Booleans and Conditionals

LISP uses the self-evaluating symbol `nil` to mean false. Anything other than `nil` means true. Unless we have a reason not to, we usually use the self-evaluating symbol `t` to stand for true.

LISP provides a standard set of logical functions, for example `and`, `or`, and `not`. The `and` and `or` connectives are short-circuiting: and will not evaluate any arguments to the right of the first one which evaluates to `nil`, while `or` will not evaluate any arguments to the right of the first one which evaluates to `t` (with `t` we mean here ``non-`nil`'').

LISP also provides several special forms for conditional execution. The simplest of these is `if`. The first argument of `if` determines whether the second or third argument will be executed:

``` > (if t 5 6) 5 > (if nil 5 6) 6 > (if 4 5 6) 5 ```

If you need to put more than one statement in the then or else clause of an if statement, you can use the `progn` special form. `Progn` executes each statement in its body, then returns the value of the final one.

``` > (setq a 7) 7 > (setq b 0) 0 > (setq c 5) 5 > (if (> a 5) (progn (setq a (+ b 7)) (setq b (+ c 8))) (setq b 4)) 13 ```

An `if` statement which lacks either a then or an else clause can be written using the `when` or `unless` special form:

``` > (when t 3) 3 > (when nil 3) NIL > (unless t 3) NIL > (unless nil 3) 3 ```

`When` and `unless`, unlike `if`, allow any number of statements in their bodies. (Eg, `(when x a b c)` is equivalent to `(if x (progn a b c))`.)

``` > (when t (setq a 5) (+ a 6)) 11 ```

More complicated conditionals can be defined using the `cond` special form, which is equivalent to an if ... else if ... fi construction.

A `cond` consists of the symbol `cond` followed by a number of cond clauses, each of which is a list. The first element of a cond clause is the condition; the remaining elements (if any) are the action. The cond form finds the first clause whose condition evaluates to true (ie, doesn't evaluate to nil); it then executes the corresponding action and returns the resulting value. None of the remaining conditions are evaluated; nor are any actions except the one corresponding to the selected condition. For example:

``` > (setq a 3) 3 > (cond ((evenp a) a) ;if a is even return a ((> a 7) (/ a 2)) ;else if a is bigger than 7 return a/2 ((< a 5) (- a 1)) ;else if a is smaller than 5 return a-1 (t 17)) ;else return 17 2 ```

If the action in the selected cond clause is missing, `cond` returns what the condition evaluated to:

``` > (cond ((+ 3 4))) 7 ```

Here's a clever little recursive function which uses `cond`. You might be interested in trying to prove that it terminates for all integers `x` at least 1. (If you succeed, please publish the result.)

``` > (defun hotpo (x steps) ;hotpo stands for Half Or Triple Plus One (cond ((= x 1) steps) ((oddp x) (hotpo (+ 1 (* x 3)) (+ 1 steps))) (t (hotpo (/ x 2) (+ 1 steps))))) A > (hotpo 7 0) 16 ```

The LISP case statement is like a C switch statement:

``` > (setq x 'b) B > (case x (a 5) ((d e) 7) ((b f) 3) (otherwise 9)) 3 ```

The otherwise clause at the end means that if `x` is not `a`, `b`, `d`, `e`, or `f`, the case statement will return 9.