マッピングとは、関数をシーケンスの各要素に適用し、新しいシーケンスを作り出すことを指します。
mapcarを使うと、関数をオブジェクトの配列にマッピングできます。
(mapcar #'double '(1 2 3 4)) ; => (2 4 6 8)
最初の引数が、呼び出す関数であることに注目してください。#'は、関数を指定するための特別なクォート構文です。(ここでは'doubleを使うこともできますが、#'を使うのが慣用的で、いわば「より正しい」書き方です。)
マッピングは、1つのシーケンスに関数を適用する場合に限りません。複数のシーケンスに対しても行えます。N個のシーケンスを渡す場合、関数はN個の引数を受け取る必要があります。
(mapcar #'list '(1 2) '(a b) '("foo" "bar")) ; => ((1 a "foo") (2 b "bar"))
mapcarのほかにも、配列をマッピングするための関数がいくつかあります。mapcarが最もよく使われるのは間違いありませんが、ほかの関数についても知っておくとよいでしょう。
maplistはmapcarと似た働きをしますが、要素ではなく、連続する部分配列に対して処理を行います。最初は配列全体、次にcdr、さらにそのcdr、というように進みます。
(maplist #'identity '(a b c)) ; => ((A B C) (B C) (C))
mapcとmaplは、それぞれmapcarとmaplistに似ていますが、結果を集めず、代わりに最初の配列を返します。これは副作用を目的とする操作で使います。
mapcanとmapconはmapcarとmaplistに似ていますが、結果はnconcによって平坦化されます。nconcはappendに似ていますが、最後の引数以外を破壊的に変更します。
マッピングは配列に限られません。(別のコンセプトで扱う)どんなシーケンスでもマッピングできます。配列以外のシーケンスの場合は、map関数を使います。
mapは3つ以上の引数を取ります。
(map 'list #'double '(1 2 3)) ; => (2 4 6)
(map 'string #'char-upcase "foobar") ; => "FOOBAR"
特殊なケースとして、結果のシーケンスの型にnilを指定すると、nilが返されます。これ(および上記のmapcとmapl)は、副作用のために使われます。