Mapping

Another important aspect of the functional style is the use of higher-order functions, functions that take other functions as arguments or return functions as values. You saw several examples of higher-order functions, such as **MAP**, in the previous chapter. Although **MAP** can be used with both lists and vectors (that is, with any kind of sequence), Common Lisp also provides six mapping functions specifically for lists. The differences between the six functions have to do with how they build up their result and whether they apply the function to the elements of the list or to the cons cells of the list structure.

**MAPCAR** is the function most like **MAP**. Because it always returns a list, it doesn’t require the result-type argument **MAP** does. Instead, its first argument is the function to apply, and subsequent arguments are the lists whose elements will provide the arguments to the function. Otherwise, it behaves like **MAP**: the function is applied to successive elements of the list arguments, taking one element from each list per application of the function. The results of each function call are collected into a new list. For example:

  1. (mapcar #'(lambda (x) (* 2 x)) (list 1 2 3)) ==> (2 4 6)
  2. (mapcar #'+ (list 1 2 3) (list 10 20 30)) ==> (11 22 33)

**MAPLIST** is just like **MAPCAR** except instead of passing the elements of the list to the function, it passes the actual cons cells.13 Thus, the function has access not only to the value of each element of the list (via the **CAR** of the cons cell) but also to the rest of the list (via the **CDR**).

**MAPCAN** and **MAPCON** work like **MAPCAR** and **MAPLIST** except for the way they build up their result. While **MAPCAR** and **MAPLIST** build a completely new list to hold the results of the function calls, **MAPCAN** and **MAPCON** build their result by splicing together the results—which must be lists—as if by **NCONC**. Thus, each function invocation can provide any number of elements to be included in the result.14 **MAPCAN**, like **MAPCAR**, passes the elements of the list to the mapped function while **MAPCON**, like **MAPLIST**, passes the cons cells.

Finally, the functions **MAPC** and **MAPL** are control constructs disguised as functions—they simply return their first list argument, so they’re useful only when the side effects of the mapped function do something interesting. **MAPC** is the cousin of **MAPCAR** and **MAPCAN** while **MAPL** is in the **MAPLIST**/**MAPCON** family.