LEARNING LISP

Contents | Scope Considerations | Isplay Ogrammingpray

Maps

We are going to make life with Lisp much simpler. The careful reader may have noticed some patterns in the recursive Lisp functions that we have been defining. Lisp provides built-in functions to perform a number of these patterns.

Suppose that we want to perform the same operation on each element of a list in succession. There is a Lisp function to do this: MAPCAR. Let's first try an example.

:(MAPCAR 'PRINT'(ALL THE NEWS THAT FITS))
  ALL
  THE
  NEWS
  THAT
  FITS

  (ALL THE NEWS THAT FITS )
What happened? Well, we used the PRINT on each element of the list. This caused the first five lines of the result. [Each PRINT took up one line.] Lisp then collected all of the results of the PRINTs into a list and returned this collection as the result of the expression. We normally won't want to use the PRINT function on each element of a list; let's try some more interesting examples. INT is a new Lisp function that returns the value of its argument preceding the decimal point, if any. For example, (INT 33.89) is 33. Now for EVEN. It is a predicate that works by dividing the argument by two and determining whether that result is the same as the integer part of the number divided by 2. Here's EVEN:
:(DEFINE (EVEN (LAMBDA (N)

: (EQUAL (DIV N 2) (INT (DIV N 2)))))))

  EVEN
Now we can use MAPCAR to apply EVEN to all the members of a list.
:(MAPCAR 'EVEN '(0 1 2 3 4 ))

  (T NIL T NIL T )

:(MAPCAR 'LENGTH '(() (A) (B B) (C D E)))

  (0 1 2 3 )

:(MAPCAR 'REVERSE '((ARE WE) (IN NOT)

:(TOTO KANSAS)))))

  ((WE ARE ) (NOT IN ) (KANSAS TOTO ) )
The exact definition for MAPCAR is as follows: As its arguments MAPCAR takes a function name and a list. First, use the given function on the CAR of the list. Then continue using the same function with the CDR of the list. When finished, make a list of all the individual results.

In the first example above, Lisp applied the function EVEN to each element of the list: "(0 1 2 3 4)". In the second example, LENGTH was used on each element of its associated list. In the last example, we used the REVERSE function on each element. Note that this is sort of the complement of the regular use of the REVERSE function which REVERSEs all of the top level elements of a list. Here we REVERSEd the elements of each sublist but left the order of sublists intact.

A recursive Lisp function equivalent to the first example is presented below.

:(DEFINE (EVENMAP (LAMBDA (L)

:  (COND

:  (( NULL L) NIL)

:   (T (CONS (EVEN (CAR L))

:   (EVENMAP (CDR L))))))))
  EVENMAP
:(EVENMAP '(0 1 2 3 4 5 6 7 8)
:))

  (T NIL T NIL T NIL T NIL T )

Contents | Scope Considerations | Isplay Ogrammingpray