#drnseccondprog2#2503>
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 <#2504#>interval<#2504#> into which the savings amount
falls. To assist their bank clerks, banks deploy 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 <#60704#><#2505#>CONDITIONAL FUNCTION<#2505#><#60704#>,
and we formulate the definition of such functions using <#60705#><#2506#>CONDITIONAL EXPRESSIONS<#2506#><#60705#>. The general shape of a conditional expression
is
<#2511#>(c<#2511#><#2512#>ond<#2512#>
<#2513#>[<#2513#><#2514#>question<#2514#> <#2515#>answer]<#2515#>
<#2516#>...<#2516#>
<#2517#>[<#2517#><#2518#>question<#2518#> <#2519#>answer]<#2519#><#2520#>)<#2520#>
<#2523#>or<#2523#> <#2527#>(c<#2527#><#2528#>ond<#2528#>
<#2529#>[<#2529#><#2530#>question<#2530#> <#2531#>answer]<#2531#>
<#2532#>...<#2532#>
<#2533#>[<#2533#><#2534#>else<#2534#> <#2535#>answer]<#2535#><#2536#>)<#2536#>
The dots indicate that a <#60706#><#2540#>cond<#2540#>-expression<#60706#> may contain an arbitrary
number of <#60707#><#2541#>cond<#2541#><#60707#>-lines. Each <#60708#><#2542#>cond<#2542#><#60708#>-line, also called a
<#60709#><#2543#>cond<#2543#><#60709#>-clause, contains two expressions, called <#60710#><#2544#>CONDITION<#2544#><#60710#>
and <#60711#><#2545#>ANSWER<#2545#><#60711#>. A <#2546#>condition<#2546#> 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.
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:
<#2553#>(c<#2553#><#2554#>ond<#2554#>
<#2555#>[<#2555#><#2556#>(;SPMlt;<#2556#> <#2557#>n<#2557#> <#2558#>10)<#2558#> <#2559#>5.0]<#2559#>
<#2560#>[<#2560#><#2561#>(;SPMlt;<#2561#> <#2562#>n<#2562#> <#2563#>20)<#2563#> <#2564#>5]<#2564#>
<#2565#>[<#2565#><#2566#>(;SPMlt;<#2566#> <#2567#>n<#2567#> <#2568#>30)<#2568#> <#2569#>true<#2569#><#2570#>]<#2570#><#2571#>)<#2571#>
<#2577#>(c<#2577#><#2578#>ond<#2578#>
<#2579#>[<#2579#><#2580#>(;SPMlt;<#2580#> <#2581#>n<#2581#> <#2582#>10)<#2582#> <#2583#>30<#2583#> <#2584#>12]<#2584#>
<#2585#>[<#2585#><#2586#>(;SPMgt;<#2586#> <#2587#>n<#2587#> <#2588#>25)<#2588#> <#2589#>false<#2589#><#2590#>]<#2590#>
<#2591#>[<#2591#><#2592#>(;SPMgt;<#2592#> <#2593#>n<#2593#> <#2594#>20)<#2594#> <#2595#>0]<#2595#><#2596#>)<#2596#>
The left one is a valid <#60714#><#2600#>cond<#2600#>-expression<#60714#> because each
<#60715#><#2601#>cond<#2601#><#60715#>-line contains two expressions. In contrast, the right one is
<#2602#>not<#2602#> a valid <#60716#><#2603#>cond<#2603#>-expression<#60716#>. Its first line contains three
expressions instead of two.
When Scheme evaluates a <#60717#><#2604#>cond<#2604#>-expression<#60717#>, it determines the value
of each condition, one by one. A condition must evaluate to <#60718#><#2605#>true<#2605#><#60718#> or
<#60719#><#2606#>false<#2606#><#60719#>. For the first condition that evaluates to <#60720#><#2607#>true<#2607#><#60720#>, Scheme
evaluates the corresponding answer, and the value of the answer is the
value of the entire <#60721#><#2608#>cond<#2608#>-expression<#60721#>. If the last condition is
<#60722#><#2609#>else<#2609#><#60722#> and all other conditions fail, the answer for the
<#60723#><#2610#>cond<#2610#><#60723#> is the value of the last answer expression.
Here are two simple examples:
<#2619#>(c<#2619#><#2620#>ond<#2620#>
<#2621#>[<#2621#><#2622#>(;SPMlt;=<#2622#> <#2623#>n<#2623#> <#2624#>1000)<#2624#> <#2625#>.040]<#2625#>
<#2626#>[<#2626#><#2627#>(;SPMlt;=<#2627#> <#2628#>n<#2628#> <#2629#>5000)<#2629#> <#2630#>.045]<#2630#>
<#2631#>[<#2631#><#2632#>(;SPMlt;=<#2632#> <#2633#>n<#2633#> <#2634#>10000)<#2634#> <#2635#>.055]<#2635#>
<#2636#>[<#2636#><#2637#>(;SPMgt;<#2637#> <#2638#>n<#2638#> <#2639#>10000)<#2639#> <#2640#>.060]<#2640#><#2641#>)<#2641#>
<#2647#>(c<#2647#><#2648#>ond<#2648#>
<#2649#>[<#2649#><#2650#>(;SPMlt;=<#2650#> <#2651#>n<#2651#> <#2652#>1000)<#2652#> <#2653#>.040]<#2653#>
<#2654#>[<#2654#><#2655#>(;SPMlt;=<#2655#> <#2656#>n<#2656#> <#2657#>5000)<#2657#> <#2658#>.045]<#2658#>
<#2659#>[<#2659#><#2660#>(;SPMlt;=<#2660#> <#2661#>n<#2661#> <#2662#>10000)<#2662#> <#2663#>.055]<#2663#>
<#2664#>[<#2664#><#2665#>else<#2665#> <#2666#>.060]<#2666#><#2667#>)<#2667#>
If we replace <#60727#><#2671#>n<#2671#><#60727#> with <#60728#><#2672#>20000<#2672#><#60728#>, the first three conditions
evaluate to <#60729#><#2673#>false<#2673#><#60729#> in both expressions. For the expression on the left
the fourth condition, <#60730#><#2674#>(;SPMgt;<#2674#>\ <#2675#>20000<#2675#>\ <#2676#>10000)<#2676#><#60730#>, evaluates to <#60731#><#2677#>true<#2677#><#60731#>
and therefore the answer is <#60732#><#2678#>0.60<#2678#><#60732#>. For the expression on the right,
the <#60733#><#2679#>else<#2679#><#60733#> clause specifies what the result of the entire expression
is. In contrast, if <#60734#><#2680#>n<#2680#><#60734#> is <#60735#><#2681#>10000<#2681#><#60735#>, the value of is
<#60736#><#2682#>.055<#2682#><#60736#> because for both expressions, <#60737#><#2683#>(;SPMlt;=<#2683#>\ <#2684#>10000<#2684#>\ <#2685#>1000)<#2685#><#60737#> and
<#60738#><#2686#>(;SPMlt;=<#2686#>\ <#2687#>10000<#2687#>\ <#2688#>5000)<#2688#><#60738#> evaluate to <#60739#><#2689#>false<#2689#><#60739#> and
<#60740#><#2690#>(;SPMlt;=<#2690#>\ <#2691#>10000<#2691#>\ <#2692#>10000)<#2692#><#60740#> evaluates to <#60741#><#2693#>true<#2693#><#60741#>.
<#2696#>Exercise 4.3.1<#2696#>
Decide which of the following two <#60742#><#2698#>cond<#2698#>-expression<#60742#>s is legal:
<#2703#>(c<#2703#><#2704#>ond<#2704#>
<#2705#>[<#2705#><#2706#>(;SPMlt;<#2706#> <#2707#>n<#2707#> <#2708#>10)<#2708#> <#2709#>20]<#2709#>
<#2710#>[<#2710#><#2711#>(;SPMgt;<#2711#> <#2712#>n<#2712#> <#2713#>20)<#2713#> <#2714#>0]<#2714#>
<#2715#>[<#2715#><#2716#>else<#2716#> <#2717#>1]<#2717#><#2718#>)<#2718#>
<#2724#>(c<#2724#><#2725#>ond<#2725#>
<#2726#>[<#2726#><#2727#>(;SPMlt;<#2727#> <#2728#>n<#2728#> <#2729#>10)<#2729#> <#2730#>20]<#2730#>
<#2731#>[<#2731#><#2732#>(and<#2732#> <#2733#>(;SPMgt;<#2733#> <#2734#>n<#2734#> <#2735#>20)<#2735#> <#2736#>(;SPMlt;=<#2736#> <#2737#>n<#2737#> <#2738#>30))]<#2738#>
<#2739#>[<#2739#><#2740#>else<#2740#> <#2741#>1]<#2741#><#2742#>)<#2742#>
Explain why the other one is not. Why is
<#2750#>(c<#2750#><#2751#>ond<#2751#>
<#2752#>[<#2752#><#2753#>(;SPMlt;<#2753#> <#2754#>n<#2754#> <#2755#>10)<#2755#> <#2756#>20]<#2756#>
<#2757#>[<#2757#><#2758#>*<#2758#> <#2759#>10<#2759#> <#2760#>n]<#2760#>
<#2761#>[<#2761#><#2762#>else<#2762#> <#2763#>555]<#2763#><#2764#>)<#2764#>
not a valid <#60743#><#2768#>cond<#2768#>-expression<#60743#>?~ Solution<#60744#><#60744#>
<#2774#>Exercise 4.3.2<#2774#>
What is the value of the above <#60745#><#2776#>cond<#2776#>-expression<#60745#>s for
(a) <#60746#><#2777#>n<#2777#>\ <#2778#>=<#2778#>\ <#2779#>500<#2779#><#60746#>, (b) <#60747#><#2780#>n<#2780#>\ <#2781#>=<#2781#>\ <#2782#>2800<#2782#><#60747#>, and (c) <#60748#><#2783#>n<#2783#>\ <#2784#>=<#2784#>\ <#2785#>15000<#2785#><#60748#>? Solution<#60749#><#60749#>
<#2791#>Exercise 4.3.3<#2791#>
What is the value of
<#2797#>(c<#2797#><#2798#>ond<#2798#>
<#2799#>[<#2799#><#2800#>(;SPMlt;=<#2800#> <#2801#>n<#2801#> <#2802#>1000)<#2802#> <#2803#>(*<#2803#> <#2804#>.040<#2804#> <#2805#>1000)]<#2805#>
<#2806#>[<#2806#><#2807#>(;SPMlt;=<#2807#> <#2808#>n<#2808#> <#2809#>5000)<#2809#> <#2810#>(+<#2810#> <#2811#>(*<#2811#> <#2812#>1000<#2812#> <#2813#>.040)<#2813#>
<#2814#>(*<#2814#> <#2815#>(-<#2815#> <#2816#>n<#2816#> <#2817#>1000)<#2817#> <#2818#>.045))]<#2818#>
<#2819#>[<#2819#><#2820#>else<#2820#> <#2821#>(+<#2821#> <#2822#>(*<#2822#> <#2823#>1000<#2823#> <#2824#>.040)<#2824#>
<#2825#>(*<#2825#> <#2826#>4000<#2826#> <#2827#>.045)<#2827#>
<#2828#>(*<#2828#> <#2829#>(-<#2829#> <#2830#>n<#2830#> <#2831#>10000)<#2831#> <#2832#>.055))]<#2832#><#2833#>)<#2833#>
for (a) <#60750#><#2837#>n<#2837#>\ <#2838#>=<#2838#>\ <#2839#>500<#2839#><#60750#>, (b) <#60751#><#2840#>n<#2840#>\ <#2841#>=<#2841#>\ <#2842#>2800<#2842#><#60751#>, and (c) <#60752#><#2843#>n<#2843#>\ <#2844#>=<#2844#>\ <#2845#>15000<#2845#><#60752#>?
Solution<#60753#><#60753#>
With the help of <#60754#><#2853#>cond<#2853#>-expression<#60754#>s, 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:
<#70719#>;; <#60755#><#2858#>interest-rate<#2858#> <#2859#>:<#2859#> <#2860#>number<#2860#> <#2861#><#2861#><#2862#>-;SPMgt;<#2862#><#2863#><#2863#> <#2864#>number<#2864#><#60755#><#70719#>
<#70720#>;; to determine the interest rate for the given <#60756#><#2865#>amount<#2865#><#60756#><#70720#>
<#2866#>(define<#2866#> <#2867#>(interest-rate<#2867#> <#2868#>amount)<#2868#> <#2869#>...)<#2869#>
Furthermore, the problem statement provides three examples:
- <#60757#><#2874#>(interest-rate<#2874#>\ <#2875#>1000)<#2875#>\ <#2876#>=<#2876#>\ <#2877#>.040<#2877#><#60757#>
- <#60758#><#2878#>(interest-rate<#2878#>\ <#2879#>5000)<#2879#>\ <#2880#>=<#2880#>\ <#2881#>.045<#2881#><#60758#>
- <#60759#><#2882#>(interest-rate<#2882#>\ <#2883#>8000)<#2883#>\ <#2884#>=<#2884#>\ <#2885#>.050<#2885#><#60759#>
The body of the function must be a <#60760#><#2887#>cond<#2887#>-expression<#60760#> that
distinguishes the three cases mentioned in the problem statement. Here is a
sketch:
<#2892#>(c<#2892#><#2893#>ond<#2893#>
<#2894#>[<#2894#><#2895#>(;SPMlt;=<#2895#> <#2896#>amount<#2896#> <#2897#>1000)<#2897#> <#2898#>...]<#2898#>
<#2899#>[<#2899#><#2900#>(;SPMlt;=<#2900#> <#2901#>amount<#2901#> <#2902#>5000)<#2902#> <#2903#>...]<#2903#>
<#2904#>[<#2904#><#2905#>(;SPMgt;<#2905#> <#2906#>amount<#2906#> <#2907#>5000)<#2907#> <#2908#>...]<#2908#><#2909#>)<#2909#>
Using the examples and the outline of the <#60761#><#2913#>cond<#2913#>-expression<#60761#>, the answers
are easy:
<#2919#>(d<#2919#><#2920#>efine<#2920#> <#2921#>(interest-rate<#2921#> <#2922#>amount)<#2922#>
<#2923#>(c<#2923#><#2924#>ond<#2924#>
<#2925#>[<#2925#><#2926#>(;SPMlt;=<#2926#> <#2927#>amount<#2927#> <#2928#>1000)<#2928#> <#2929#>0.040]<#2929#>
<#2930#>[<#2930#><#2931#>(;SPMlt;=<#2931#> <#2932#>amount<#2932#> <#2933#>5000)<#2933#> <#2934#>0.045]<#2934#>
<#2935#>[<#2935#><#2936#>(;SPMgt;<#2936#> <#2937#>amount<#2937#> <#2938#>5000)<#2938#> <#2939#>0.050]<#2939#><#2940#>))<#2940#>
Since we know that the function only requires three cases, we can also replace
the last condition with <#60762#><#2944#>else<#2944#><#60762#>:
<#2949#>(d<#2949#><#2950#>efine<#2950#> <#2951#>(interest-rate<#2951#> <#2952#>amount)<#2952#>
<#2953#>(c<#2953#><#2954#>ond<#2954#>
<#2955#>[<#2955#><#2956#>(;SPMlt;=<#2956#> <#2957#>amount<#2957#> <#2958#>1000)<#2958#> <#2959#>0.040]<#2959#>
<#2960#>[<#2960#><#2961#>(;SPMlt;=<#2961#> <#2962#>amount<#2962#> <#2963#>5000)<#2963#> <#2964#>0.045]<#2964#>
<#2965#>[<#2965#><#2966#>else<#2966#> <#2967#>0.050]<#2967#><#2968#>))<#2968#>
~<#60763#>Neither form is preferable. For beginners, it might be better to spell all out all conditions. If they make a mistake, Scheme will signal a run-time error. If they use <#2973#>else<#2973#>, the function will produce the value of the <#2974#>else<#2974#>-clause, even though the conditions may be set up wrong.<#60763#>
When we apply <#60764#><#2975#>interest-rate<#2975#><#60764#> to an amount, say <#60765#><#2976#>4000<#2976#><#60765#>, the
calculation proceeds as usual. Scheme first copies the body of the
function and replaces <#60766#><#2977#>amount<#2977#><#60766#> by <#60767#><#2978#>4000<#2978#><#60767#>:
<#2983#>(interest-rate<#2983#> <#2984#>4000)<#2984#>
<#2985#>=<#2985#> <#2986#>(c<#2986#><#2987#>ond<#2987#>
<#2988#>[<#2988#><#2989#>(;SPMlt;=<#2989#> <#2990#>4000<#2990#> <#2991#>1000)<#2991#> <#2992#>0.040]<#2992#>
<#2993#>[<#2993#><#2994#>(;SPMlt;=<#2994#> <#2995#>4000<#2995#> <#2996#>5000)<#2996#> <#2997#>0.045]<#2997#>
<#2998#>[<#2998#><#2999#>else<#2999#> <#3000#>0.050]<#3000#><#3001#>)<#3001#>
<#3002#>=<#3002#> <#3003#>0.045<#3003#>
The first condition is <#60768#><#3007#>false<#3007#><#60768#> but the second one is <#60769#><#3008#>true<#3008#><#60769#>, so
the result is <#60770#><#3009#>0.045<#3009#><#60770#> or 4.5. The evaluation would proceed in the
same manner if we had used the variant of the function with <#60771#><#3010#>(;SPMgt;<#3010#>\ <#3011#>amount<#3011#><#3012#> <#3012#><#3013#>5000)<#3013#><#60771#> instead of <#60772#><#3014#>else<#3014#><#60772#>.