COM1340 - Winter 2003
Higher-order operations on lists
February 19, 2003

Scheme allows procedures to be passed as arguments to other procedures, and returned as the result of procedure applications. In this sense, procedures are like any other data, so they are ``first-class.'' Many programming languages either disallow the passing and returning of procedures, or restrict this ability in certain ways.
Why do we want to pass in procedures? Consider a list-sorting function that is parameterized by a comparison function:
  (define (sorter lst cmp)
    ... ) 

By varying the cmp argument, we can sort lists containing different kinds of data and the direction of the sort, and so on. Those familiar with C/C++ may recognize a similarity here with the standard library function qsort(), which takes a function pointer argument. In this handout, we'll see other uses for passed-in procedures.

Why do we want to return procedures? Often, we want to create a class of related functions specialized to particular values:

  (define (make-adder n)
    (lambda (m) (+ n m)))

  (define add3 (make-adder 3))
  (define add42 (make-adder 42))

When applied to a value, the make-adder procedure returns a procedure of one argument. Question: what happens when make-adder is applied to a value other than a number?

Scheme has a map function that takes a procedure of arguments and lists, each of length . It returns a list of length consisting of the result of applying to corresponding elements in the argument lists. Examples:
  (map + '(1 2 3) '(4 5 6)) => (5 7 9)
  (map add3 '(11 22 33)) => (14 25 36)

When map is applied to a single list, we can consider it a homomorphism (a structure-preserving map in the mathematical sense) because it preserves the structure of the input list. When applied to two or more lists, map squeezes the result into a single list.
Class exercise: write map that takes a procedure and just one list as input.

Last modified: Wed, Feb 12, 2003, 12:10 pm US/Eastern
HTML conversion by TeX2page 4p14a