# 3.7 Decisions

To make more useful procedures, we need the actions taken to depend on
the input values. For example, we may want a procedure that takes two
numbers as inputs and evaluates to the greater of the two inputs. To
define such a procedure we need a way of making a decision. The
*IfExpression* expression provides a way of using the result of one
expression to select which of two possible expressions to evaluate:

Expression |
::$\Rightarrow$ | IfExpression |

IfExpression |
::$\Rightarrow$ | (if Expression$_{Predicate}$ |

Expression$_{Consequent}$ | ||

Expression$_{Alternate}$) |

The *IfExpression* replacement has three *Expression* terms. For
clarity, we give each of them names as denoted by the Predicate,
Consequent, and Alternate subscripts. To evaluate an *IfExpression*,
first evaluate the predicate expression, *Expression$_{Predicate}$*. If it evaluates to any non-false value, the value of the
*IfExpression* is the value of *Expression$_{Consequent}$*, the
consequent expression, and the alternate expression is not evaluated at
all. If the predicate expression evaluates to false, the value of the
*IfExpression* is the value of *Expression$_{Alternate}$*, the
alternate expression, and the consequent expression is not evaluated at
all.

The predicate expression determines which of the two following
expressions is evaluated to produce the value of the *IfExpression*. If
the value of the predicate is *anything* other than |false|, the
consequent expression is used. For example, if the predicate evaluates
to |true|, to a number, or to a procedure the consequent expression is
evaluated.

The if expression is a *special form*. This means that although it looks
syntactically identical to an application (that is, it could be an
application of a procedure named `if`

), it is not evaluated as a normal
application would be. Instead, we have a special evaluation rule for if
expressions. The reason a special evaluation rule is needed is because
we do not want all the subexpressions to be evaluated. With the normal
application rule, all the subexpressions are evaluated first, and then
the procedure resulting from the first subexpression is applied to the
values resulting from the others. With the if special form evaluation
rule, the predicate expression is always evaluated first and only one of
the following subexpressions is evaluated depending on the result of
evaluating the predicate expression.

This means an if expression can evaluate to a value even if evaluating one of its subexpressions would produce an error. For example,

evaluates to `7`

even though evaluating the subexpression `(* + +)`

would produce an error. Because of the special evaluation rule for if expressions, the consequent expression is never evaluated.

Now that we have procedures, decisions, and definitions, we can understand the |bigger| procedure from the beginning of the chapter. The definition,

is a condensed procedure definition. It is equivalent to:

This defines the name `bigger`

as the value of
evaluating the procedure expression `(lambda (a b) (if ( > a b) a b))`

.
This is a procedure that takes two inputs, named `a`

and `b`

. Its body
is an if expression with predicate expression `( > a b)`

. The predicate
expression compares the value that is bound to the first parameter, `a`

,
with the value that is bound to the second parameter, `b`

, and evaluates
to `true`

if the value of the first parameter is greater, and `false`

otherwise. According to the evaluation rule for an if expression, when
the predicate evaluates to any non-false value (in this case, `true`

),
the value of the if expression is the value of the consequent
expression, `a`

. When the predicate evaluates to `false`

, the value of
the if expression is the value of the alternate expression, `b`

. Hence,
our `bigger`

procedure takes two numbers as inputs and produces as
output the greater of the two inputs.

**Exercise 3.7. ** Follow the evaluation rules to evaluate the Scheme
expression:

where `bigger is the procedure defined above. (It is very tedious to follow all of the steps (that’s why we normally rely on computers to do it!), but worth doing once to make sure you understand the evaluation rules.)

**Exercise 3.8.** Define a procedure, `xor`

, that implements the
logical exclusive-or operation. The `xor`

function takes two inputs,
and outputs `true`

if exactly one of those outputs has a true value.
Otherwise, it outputs `false`

. For example, `(xor true true)`

should
evaluate to `false`

and `(xor ( \< 3 5) (= 8 8))`

should evaluate to
`true`

.

**Exercise 3.9. ** Define a procedure, `absvalue`

, that takes a number
as input and produces the absolute value of that number as its output.
For example, `(absvalue 3)`

should evaluate to `3`

and `(absvalue -150)`

should evaluate to `150`

.

**Exercise 3.10. **Define a procedure, `bigger-magnitude`

, that takes
two inputs, and outputs the value of the input with the greater
magnitude (that is, absolute distance from zero). For example,
`(bigger-magnitude 5 -7)`

should evaluate to `-7`

, and
`(bigger-magnitude 9 -3)`

should evaluate to `9`

.

**Exercise 3.11. ** Define a procedure, `biggest`

, that takes three
inputs, and produces as output the maximum value of the three inputs.
For example, `(biggest 5 7 3)`

should evaluate to `7`

. Find at least two
different ways to define `biggest`

, one using `bigger`

, and one without
using it.