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 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.walker.cs.grinnell.edu/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
Valid HTML 4.01! Valid CSS!
For more information, please contact Henry M. Walker at walker@cs.grinnell.edu.