Procedures as Values

In this lab, you will experiment with many variations of the concept of using procedures as values.

Exercises

Exercise 1: Tally

Here are three procedures with similar structures. The first one finds out how many even numbers there are in a given list of integers; the second finds out how many whitespace characters there in a given list of characters; the third one finds out how many of the elements of a given list are symbols.

```(define even-tally
(lambda (ls)
(cond ((null? ls) 0)
((even? (car ls)) (+ (even-tally (cdr ls)) 1))
(else (even-tally (cdr ls))))))

(define whitespace-tally
(lambda (ls)
(cond ((null? ls) 0)
((char-whitespace? (car ls)) (+ (whitespace-tally (cdr ls)) 1))
(else (whitespace-tally (cdr ls))))))

(define symbol-tally
(lambda (ls)
(cond ((null? ls) 0)
((symbol? (car ls)) (+ (symbol-tally (cdr ls)) 1))
(else (symbol-tally (cdr ls))))))
```

a. Write a procedure, `(tally predicate lst)` that counts the number of values in a list that meet a particular predicate.

b. Define each of the previous procedures in terms of `tally`.

Exercise 2: Preconditions for Tallying

What preconditions should `tally` have? Why?

We'll discuss this exercise at the end of lab.

Exercise 3: Getting Keys

Use `map` to give a concise definition of a procedure `association-list-keys` that takes one argument, an association list, and returns a list of the keys for that association list.

Exercise 4: Mapping on Multiple Lists

The `map` procedure can actually take more than two arguments, if all of the extras are lists:

```> (map string-append (list "left" "start" "beginning")
(list "-to-" "-to-" "-to-")
(list "right" "finish" "end"))
("left-to-right" "start-to-finish" "beginning-to-end")

> (map cons (list 'a 'b 'c) (list 'd 'e 'f))
((a . d) (b . e) (c . f))
```

Using `map`, define a procedure, `pairwise-max` that takes as arguments two lists of numbers, equal in length, and returns a new list whose components are the largest of each corresponding pair of values of the arguments. For example,

```> (pairwise-max '(2 3 4 5) '(6 4 2 8))
(6 4 4 8)
```

(Note the `max` is built in to Scheme.)

Exercise 5: Preconditions to `pairwise-max`

a. What happens if you provide your previous procedure with different length lists?

b. What preconditions should `pairwise-max` have?

Exercise 6: Procedures as Return Values

You've seen that procedures can be parameters. Procedures can also be return values from other procedures. Consider the following procedure, `(make-add val)` that creates a procedure that adds val to its argument.

```(define make-add
(lambda (val)
(lambda (x) (+ val x))))
```

a. What happens if you ask for `(make-add 2)`?

b. What happens when you enter the following code?

```(define add1 (make-add 1))
```

c. What happens when you enter the following?

```(let ((add2 (make-add 2)))
```

d. Explain the result of `((make-add 2) 4)`

Exercise 7: Making Talliers

Define and test a procedure `make-tallier` that takes a predicate as its argument and constructs and returns a specialized tallying procedure that counts the number of elements of a given list that satisfy the predicate.

Once that procedure is defined, we should be able to write

```(define even-tally (make-tallier even?))
(define symbol-tally (make-tallier symbol?))
```

History

Friday, 27 October 2000

• Created

Disclaimer Often, these pages were created "on the fly" with little, if any, proofreading. Any or all of the information on the pages may be incorrect. Please contact me if you notice errors.