CSC 153 Grinnell College Spring, 2005 Computer Science Fundamentals Laboratory Exercise

# Procedures as First-Class Citizens

## Goals

This laboratory exercise provides practice with procedures:

• procedures passed as procedures to other procedures, and
• procedures that apply procedures to lists and other data

## Procedures as Arguments, map, apply, and eval

Consider the following procedure `every?` that takes two arguments, a predicate `pred` and a list `ls`, and determines whether or not the predicate is true of every element of the list.

```(define every?
(lambda (pred ls)
;Pre-condition:  pred is a procedure; ls is a list
;Post-conditions:  returns error if pre-conditions are not met
;                  returns #t if pred is true for every element of list
; precondition tests
(if (not (procedure? pred))
(error 'every? "The first argument must be a predicate"))
(if (not (list? ls))
(error 'every? "The second argument must be a list"))
(every-kernel pred ls)))

(define every-kernel
(lambda (pred ls)
;Pre-condition:  pred is a procedure; ls is a list
;Post-conditions:  returns #t if pred is true for every element of list
(or (null? ls)
(and (pred (car ls))         ; Invoke the predicate here!
(every-kernel pred (cdr ls))))))
```
1. Using `every?` as a model, write and test an analogous procedure `any?` that determines whether a given predicate is true of at least one element of a given list. (Note: `every?` returns `#t` if it is given an empty list; `any?` should return `#f` in this case.)

2. Consider the following procedure `capitalize` that capitalizes all letters in a string:

```(define capitalize
(lambda (str)
;Pre-condition:  str is a character string
;Post-condition:  str is returned with all letters capitalized
(list->string (map char-upcase (string->list str)))
)
)
```

Run `capitalize` on several strings to test precisely what it does.

3. Explain in a few sentences what `capitalize` does.

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

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

```

Define a procedure `pairwise-sum` that takes as arguments two lists of numbers, equal in length, and returns a new list whose components are the sums of the corresponding components of the arguments. Define this procedure using `map`.

5. Define a procedure `dot-product` that takes as arguments two lists of numbers, equal in length, and returns the sum of the products of corresponding elements of the arguments:

```> (dot-product '(3 4 -1) '(1 -2 -3))
-2

> (dot-product '(0.003 0.035) '(8 2))
0.094

> (dot-product '(5.3e4) '(2.0e-3))
106.0

> (dot-product '() '())
0
```

Use `apply` and `map` to give a concise definition of this procedure.

6. Write a procedure `do-it` that reads an expression, evaluates it, and prints the result -- paralleling one pass through the read-eval-print cycle.

7. Modify `do-it` so that it reads, evaluates, and prints multiple expressions, until the user types `(exit)`.

This document is available on the World Wide Web as

```http://www.cs.grinnell.edu/~walker/courses/153.sp05/labs/lab-procedure-arguments.shtml
```

 created March 24, 1997 by John David Stone last revised January 31, 2005 by Henry M. Walker  For more information, please contact Henry M. Walker at walker@cs.grinnell.edu.