There was a problem when proofreading this page.
Steele and Sussman
13
The Art of the Interpreter

Part One

Variable Scoping Disciplines

Procedures as Data

The simple LISP described in Part Zero can be a pleasant medium for encoding rather complex algorithms, including those of symbolic mathematics. Often lists are used for representing such structures as the set of coefficients of a polynomial or coordinates of a space vector. Many problems require one to perform an operation on each element of a list and produce a new list of the results. For example, it may be useful to make a list of the squares of each of the elements in a vector. We would write this as follows:

(DEFINE (SQUARELIST L)
        (COND ((NULL L) '())
              (T (CONS (SQUARE (CAR L))
                       (SQUARELIST (CDR L))))))

We find ourselves writing this pattern over and over again:

(DEFINE (fLIST L)
        (COND ((NULL L) '())
              (T (CONS (f (CAR L))
                       (fLIST (CDR L))))))

where f is a function defined on the elements of our list. It would be nice to be able to define an entity of the programming language which would capture this abstract pattern. The "obvious" solution is to write the variable function as a functional variable which can be accepted as an argument:

(DEFINE (MAPCAR F L)
  (COND ((NULL L) '())
        (T (CONS (F (CAR L))
                 (MAPCAR F (CDR L))))))

(MAPCAR is the traditional name of this abstraction.) Using this we could say:

(MAPCAR SQUARE '(1 2 3))

Unfortunately, this will not work in our recursion equations interpreter. Why not?

The essence of the problem is that our interpreter segregates procedures from other kinds of objects. We refer to F as a procedure but it was passed in as a variable. Procedures are only looked up in the