Conditional Expressions and Predicates

The expressive power of the class of procedures that we can define at this point is very limited, because we have no way to make tests and to perform different operations depending on the result of a test. For instance, we cannot define a procedure that computes the absolute value of a number by testing whether the number is positive, negative, or zero and taking different actions in the different cases according to the rule

This construct is called a *case analysis*, and
there is a special form in Lisp for notating such a case
analysis. It is called
`cond` (which stands for
``conditional''), and it is used as follows:

(define (abs x) (cond ((> x 0) x) ((= x 0) 0) ((< x 0) (- x))))The general form of a conditional expression is

(cond (pconsisting of the symbol_{1}e_{1}) (p_{2}e_{2}) (p_{n}e_{n}))

Conditional expressions are evaluated as follows. The predicate
p_{1} is evaluated first. If its value is false, then
p_{2} is evaluated. If p_{2}'s value is also false, then
p_{3} is evaluated. This process continues until a predicate is
found whose value is true, in which case the interpreter returns the
value of the corresponding
*consequent expression* e of the
clause as the value of the conditional expression. If none of the
p's is found to be true, the value of the `cond` is
undefined.

The word *predicate* is used for procedures that return true
or false, as well as for expressions that evaluate to true or false.
The absolute-value procedure `abs` makes use of the
primitive
predicates `>`, `<`, and `=`.^{} These take two
numbers as arguments and test whether the first number is,
respectively, greater than, less than, or equal to the second number,
returning true or false accordingly.

Another way to write the absolute-value procedure is

(define (abs x) (cond ((< x 0) (- x)) (else x)))which could be expressed in English as ``If

Here is yet another way to write the absolute-value procedure:

(define (abs x) (if (< x 0) (- x) x))This uses the special form

(if predicate consequent alternative)To evaluate an

In addition to primitive
predicates such as `<`, `=`, and `>`, there are logical
composition operations, which enable us to construct compound
predicates. The three most frequently used are these:

The interpreter
evaluates the expressions e one at a time, in left-to-right order. If
any e evaluates to false, the value of the `and`
expression is false, and the rest of the e's are not evaluated.
If all e's evaluate to true values, the value of the `and`
expression is the value of the last one.

`(or e`_{1}` ... e`_{n}`)`

The interpreter
evaluates the expressions e one at a time, in left-to-right order. If
any e evaluates to a true value, that value is
returned as the value of the `or` expression,
and the rest of the e's are not evaluated.
If all e's evaluate to false,
the value of the `or` expression is false.

`(not e)`

The value of a `not` expression is true
when the expression e evaluates to false, and false otherwise.

Notice that `and` and `or` are special forms, not procedures,
because the subexpressions are not necessarily all evaluated.
`Not` is an ordinary procedure.

As an example of how these are used, the condition that a number *x*
be in the range
5 < *x* < 10 may be expressed as

(and (> x 5) (< x 10))As another example, we can define a predicate to test whether one number is greater than or equal to another as

(define (>= x y) (or (> x y) (= x y)))or alternatively as

(define (>= x y) (not (< x y)))

**Exercise.**
Below is a sequence of expressions.
What is the result printed by the interpreter in response to each
expression? Assume that the sequence is to be evaluated in the order
in which it is presented.

10 (+ 5 3 4) (- 9 1) (/ 6 2) (+ (* 2 4) (- 4 6)) (define a 3) (define b (+ a 1)) (+ a b (* a b)) (= a b) (if (and (> b a) (< b (* a b))) b a) (cond ((= a 4) 6) ((= b 4) (+ 6 7 a)) (else 25)) (+ 2 (if (> b a) b a)) (* (cond ((> a b) a) ((< a b) b) (else -1)) (+ a 1))

**Exercise.**
Translate the following expression into prefix form

**Exercise.**
Define a procedure that takes three numbers as arguments and returns
the sum of the squares of the two larger numbers.

**Exercise.** Observe that our model of evaluation allows for combinations whose
operators are compound expressions. Use this observation to
describe the behavior of the following procedure:

(define (a-plus-abs-b a b) ((if (> b 0) + -) a b))

**Exercise.**
Ben Bitdiddle has invented a test to determine whether the interpreter
he is faced with is using applicative-order evaluation or normal-order
evaluation. He defines the following two procedures:

(define (p) (p))Then he evaluates the expression(define (test x y) (if (= x 0) 0 y))

(test 0 (p))What behavior will Ben observe with an interpreter that uses applicative-order evaluation? What behavior will he observe with an interpreter that uses normal-order evaluation? Explain your answer. (Assume that the evaluation rule for the special form