[previous] [up] [next]     [index]
Next: Designing Conditional Functions Up: Conditional Expressions and Functions Previous: Functions that Test Conditions

Conditionals and Conditional Functions

external

Some banks pay different levels of interest for saving accounts. The more a customer deposits, the more the bank pays. In such arrangements, the interest rate depends on the interval into which the savings amount falls. To assist their bank clerks, banks use interest-rate functions. An interest function consumes the amount that a customer wishes to deposit and responds with the interest that the customer receives for this amount of money.

Our interest rate function must determine which of several conditions holds for the input. We say that the function is a CONDITIONAL FUNCTION, and we formulate the definition of such functions using CONDITIONAL EXPRESSIONS. The general shape of a conditional expression is

(cond
  [question answer] 
  ... 
  [question answer]) 
or
(cond
  [question answer] 
  ... 
  [else answer]) 

The dots indicate that a cond-expression may contain an arbitrary number of cond-lines. Each cond-line, also called a cond-clause, contains two expressions, called CONDITION and ANSWER. A condition is a conditional expression that involves the parameters; the answer is a Scheme expression that computes the result from the parameters and other data if the conditional expression holds.[footnote]

Conditional expressions are the most complicated form of expressions we have encountered and will encounter. It is therefore easy to make mistakes when we write them down. Compare the following two parenthesized expressions:

(cond
  [(< n 10) 5.0] 
  [(< n 20) 5] 
  [(< n 30) true]) 
(cond
  [(< n 10) 30 12] 
  [(> n 25) false] 
  [(> n 20) 0]) 

The left one is a valid cond-expression because each cond-line contains two expressions. In contrast, the right one is not a valid cond-expression. Its first line contains three expressions instead of two.

When Scheme evaluates a cond-expression, it determines the value of each condition, one by one. A condition must evaluate to true or false. For the first condition that evaluates to true, Scheme evaluates the corresponding answer, and the value of the answer is the value of the entire cond-expression. If the last condition is else and all other conditions fail, the answer for the cond is the value of the last answer expression.[footnote]

Here are two simple examples:

(cond
  [(<= n 1000) .040] 
  [(<= n 5000) .045] 
  [(<= n 10000) .055] 
  [(> n 10000) .060]) 
(cond
  [(<= n 1000) .040] 
  [(<= n 5000) .045] 
  [(<= n 10000) .055] 
  [else .060]) 

If we replace n with 20000, the first three conditions evaluate to false in both expressions. For the expression on the left the fourth condition, (> 20000 10000), evaluates to true and therefore the answer is 0.60. For the expression on the right, the else clause specifies what the result of the entire expression is. In contrast, if n is 10000, the value is .055 because for both expressions, (<= 10000 1000) and (<= 10000 5000) evaluate to false and (<= 10000 10000) evaluates to true.


Exercises

Exercise 4.3.1

Decide which of the following two cond-expressions is legal:

(cond
  [(< n 10) 20] 
  [(> n 20) 0] 
  [else 1]) 
(cond
  [(< n 10) 20] 
  [(and (> n 20) (<= n 30))] 
  [else 1]) 

Explain why the other one is not. Why is the following illegal?

(cond [(< n 10) 20]
      [* 10 n] 
      [else 555]) ; Solution 

Exercise 4.3.2

What is the value of

(cond
  [(<= n 1000) .040] 
  [(<= n 5000) .045] 
  [(<= n 10000) .055] 
  [(> n 10000) .060]) 
when n is (a) 500, (b) 2800, and (c) 15000Solution

Exercise 4.3.3

What is the value of

(cond
  [(<= n 1000) (* .040 1000)] 
  [(<= n 5000) (+ (* 1000 .040) 
                        (* (- n 1000) .045))] 
  [else (+ (* 1000 .040) 
           (* 4000 .045) 
           (* (- n 10000) .055))]) 
when n is (a) 500, (b) 2800, and (c) 15000Solution

With the help of cond-expressions, we can now define the interest rate function that we mentioned at the beginning of this section. Suppose the bank pays 4% for deposits of up to $1,000 (inclusive), 4.5% for deposits of up to $5,000 (inclusive), and 5% for deposits of more than $5,000. Clearly, the function consumes one number and produces one:

;; interest-rate : number -> number
;; to determine the interest rate for the given amount 
(define (interest-rate amount) ...) 
Furthermore, the problem statement provides three examples:
  1. (= (interest-rate 1000) .040)
  2. (= (interest-rate 5000) .045)
  3. (= (interest-rate 8000) .050)
Recall that examples are now formulated as boolean expressions when possible.

The body of the function must be a cond-expression that distinguishes the three cases mentioned in the problem statement. Here is a sketch:

  (cond
    [(<= amount 1000) ...] 
    [(<= amount 5000) ...] 
    [(> amount 5000) ...]) 
Using the examples and the outline of the cond-expression, the answers are easy:
(define (interest-rate amount)
  (cond 
    [(<= amount 1000) 0.040] 
    [(<= amount 5000) 0.045] 
    [(> amount 5000) 0.050])) 
Since we know that the function requires only three cases, we can also replace the last condition with else:
(define (interest-rate amount)
  (cond 
    [(<= amount 1000) 0.040] 
    [(<= amount 5000) 0.045] 
    [else 0.050])) 

external

When we apply interest-rate to an amount, say, 4000, the calculation proceeds as usual. Scheme first copies the body of the function and replaces amount by 4000:

  (interest-rate 4000)
= (cond 
    [(<= 4000 1000) 0.040] 
    [(<= 4000 5000) 0.045] 
    [else 0.050]) 
= 0.045 
The first condition is false but the second one is true, so the result is 0.045 or 4.5%. The evaluation would proceed in the same manner if we had used the variant of the function with (> amount 5000) instead of else.


[previous] [up] [next]     [index]
Next: Designing Conditional Functions Up: Conditional Expressions and Functions Previous: Functions that Test Conditions

PLT