Recall the function wage from section
:
;; wage : number -> number ;; to compute the total wage (at $12 per hour) ;; of someone who worked for h hours (define (wage h) (* 12 h))The wage function consumes the number of hours some employee worked and produces the weekly wage payment. For simplicity, we assume that all employees earn the same hourly rate, namely, $12. A company, however, isn't interested in a function like wage, which computes the wage of a single employee. Instead, it wants a function that computes the wages for all of its employees, especially if there are a lot of them.
Call this new function hours->wages. It consumes a list that represents how many hours the employees of the company worked and must produce a list of the weekly wages they earned. We can represent both the input and the output as Scheme lists of numbers. Since we already have a data definition for the inputs and outputs, we can immediately start our function development:
;; hours->wages : list-of-numbers -> list-of-numbers ;; to create a list of weekly wages from a list of weekly hours (alon) (define (hours->wages alon) ...)
Next we need some examples of inputs and the corresponding outputs:
The outputs are obtained by calculating the wage for each item on the list to the left.empty (cons 28 empty) (cons 40 (cons 28 empty))empty (cons 336 empty) (cons 480 (cons 336 empty))
Given that hours->wages consumes the same class of data as, say, the function sum, and given that the shape of a function template depends only on the shape of the data definition, we can reuse the list-of-numbers template:
(define (hours->wages alon)
(cond
[(empty? alon) ...]
[else ... (first alon) ... (hours->wages (rest alon)) ...]))
Starting with this template, we can turn to the most creative step of function development: the definition of the function body. Following our recipe, we consider each cond-line in isolation, starting with the simpler case. First, assume (empty? alon) is true, which means that the input is empty. The answer in this case is empty:
(define (hours->wages alon)
(cond
[(empty? alon) empty]
[else ... (first alon) ... (hours->wages (rest alon)) ...]))
Second, assume that alon was constructed from a number and a list of numbers. The expressions in the second line remind us of this assumption, and the recipe tells us that we should state explicitly what they compute:
From here it is a short step to the complete function definition. Since we already have the list of wages for all but the first item of alon, the function must do two things to produce an output for the entire list of hours:
(cons (wage (first alon)) (hours->wages (rest alon)))And with that, we have a complete function. It is shown in figure
How do we have to change the function in figure
if we
want to give everyone a raise to $14? Solution
Exercise 10.1.2
No employee could possibly work more than 100 hours per week. To protect the company against fraud, the function should check that no item of the input list of hours->wages exceeds 100. If one of them does, the function should immediately signal the error ``too many hours''.
How do we have to change the function in figure
if we
want to perform this basic reality check? Solution
Exercise 10.1.3
Develop convertFC. The function converts a list of Fahrenheit measurements to a list of Celsius measurements. Solution
Exercise 10.1.4
Develop the function convert-euro, which converts a list of U.S. dollar amounts into a list of euro amounts. Assume the exchange rate is 1.22 euro for each dollar.
Generalize convert-euro to the function convert-euro-1, which consumes an exchange rate and a list of dollar amounts and converts the latter into a list of euro amounts. Solution
Exercise 10.1.5
Develop the function eliminate-exp to eliminate expensive toys. The
function consumes a number, called ua, and a list of toy prices,
called lotp, and produces a list of all those prices in
lotp that are below or equal to ua. For
example,
(eliminate-exp 1.0 (cons 2.95 (cons .95 (cons 1.0 (cons 5 empty))))) ;; expected value: (cons .95 (cons 1.0 empty))Solution
Exercise 10.1.6
Develop the function name-robot, which consumes a list of toy descriptions (names) and produces an equivalent list of more accurate descriptions. Specifically, it replaces all occurrences of 'robot with 'r2d2 and otherwise retains the toy descriptions in the same order.
Generalize name-robot to the function substitute. The new function consumes two symbols, called new and old, and a list of symbols. It produces a new list of symbols by substituting all occurrences of old by new. For example,
(substitute 'Barbie 'doll (cons 'robot (cons 'doll (cons 'dress empty)))) ;; expected value: (cons 'robot (cons 'Barbie (cons 'dress empty)))Solution
Exercise 10.1.7
Develop the function recall to eliminate specific toys from a list. The function consumes the name of a toy, called ty, and a list of names, called lon, and produces a list of names that contains all components of lon with the exception of ty. For example,
(recall 'robot (cons 'robot (cons 'doll (cons 'dress empty)))) ;; expected value: (cons 'doll (cons 'dress empty))Solution
Exercise 10.1.8
Develop quadratic-roots, which solves quadratic equations: see
exercises
and
. The function accepts the
coefficients a, b, and c. The computations it
performs depend on the input:
the solution is the answer.
and
the result is a list of two numbers: the first solution followed by the second solution.
Exercise 10.1.9
The cash registers at many grocery stores talk to customers. The register's computer receives the number of cents that the customer must pay and then builds a list with the following five items:
Develop the function controller, which consumes a number and produces a list according to the above description. For example, if the amount is $1.03, then the cash register evaluates (controller 103):
(controller 103) ;; expected value: (cons 1 (cons 'dollar (cons 'and (cons 3 (cons 'cents empty)))))
Hint: Scheme provides the arithmetic operations quotient and remainder, which produce the quotient and remainder of the expression n/m for integers n and m, respectively.
Once the controller returns the correct list for amounts whose dollar and cent amounts are between 0 and 20, test the controller with a computer that can speak. Set the teachpack to sound.ss, which makes two operations available: speak-word and speak-list. The first accepts a symbol or a number, the second a list of symbols and numbers. Both pronounce the symbols they consume. Evaluate the following expressions (speak-word 1), (speak-list (cons 1 (cons 'dollar empty))), and (speak-list (cons 'beautiful (cons 'lady empty))) to understand how the operations operate.
Simple Challenge: The sound teachpack contains only
the sounds for the numbers 0 through 20 and 30,
40, 50, 60, 70, 80, and
90. Because of this restriction, this challenge problem works only on
amounts with cents and dollars between 0 to 20. Implement
a controller that deals with arbitrary amounts between 0 and 99.99.
Solution