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 (consisting of the symbol cond followed by parenthesized pairs of expressions (![]()
) (
![]()
) . . . (
![]()
)
)
called clauses. The first expression in each pair is a
predicate that is, an expression whose value is
interpreted as either true or false. 17
Conditional expressions are evaluated as follows. The predicate
is evaluated first. If its value is
false, then
is evaluated. If
's value is also false, then
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
of the clause as the value of the
conditional expression. If none of the
'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 >, < and =. 18 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 x is less than
zero return -x; otherwise return x." Else
is a special symbol that can be used in place of the
in the final clause of a cond. This
causes the cond to return as its value the value of the
corresponding
whenever all previous
clauses have been bypassed. In fact, any expression that always
evaluates to a true value could be used as the
here.
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, a restricted type of
conditional that can be used when there are precisely two cases in the
case analysis. The general form of an if expression is
(if <predicate> <consequent> <alternative>)
To evaluate an if expression, the interpreter starts by evaluating the <predicate> part of the expression. If the predicate evaluates to a true value, the interpreter then evaluates the <consequent> and returns its value. Otherwise it evaluates the <alternative> and returns its value. 19
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
one at a time, in left-to-right order . If any
evaluates to false, the value of the and
expression is false, and the rest of the
's are not evaluated. If all
's evaluate to true values, the value of the
and expression is the value of the last one.
...
)
The interpreter evaluates the expressions
one at a time, in left-to-right order. If any
evaluates to a true value, that value is returned
as the value of the or expression, and the rest of the
's are not evaluated. If all
's evaluate to false, the value of the or
expression is false.
The value of a not expression is true when the expression
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 1.1
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) (+ (Exercise 1.22 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 1.3
Define a procedure that takes three numbers as arguments and returns
the sum of the squares of the two larger numbers.
Exercise 1.4
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 1.5
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))
(define (test x y)
(if (= x 0)
0
y))
Then he evaluates the expression
(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 if is the same whether the interpreter is using normal or applicative order: The predicate expression is evaluated first, and the result determines whether to evaluate the consequent or the alternative expression.)