La mappatura è l'applicazione di una funzione a ciascun elemento di una sequenza per produrre una nuova sequenza.
mapcar può essere usata per mappare una funzione su una lista di oggetti
(mapcar #'double '(1 2 3 4)) ; => (2 4 6 8)
Nota che il primo argomento è una funzione da chiamare.
Il #' è una sintassi speciale di quoting per specificare una funzione.
(Qui si può usare 'double, ma l'uso di #' è idiomatico e, si potrebbe dire, «più corretto».)
La mappatura non si limita ad applicare una funzione a una singola sequenza, ma può essere fatta con più sequenze.
Se vengono fornite N sequenze, la funzione deve accettare N argomenti.
(mapcar #'list '(1 2) '(a b) '("foo" "bar")) ; => ((1 a "foo") (2 b "bar"))
Oltre a mapcar ci sono altre funzioni per mappare sulle liste.
mapcar è senza dubbio la più comune, ma è bene conoscere anche le altre.
maplist funziona in modo simile a mapcar, ma opera su sottoliste successive invece che su singoli elementi.
Prima sull'intera lista, poi sul cdr, poi sul cdr di quello e così via:
(maplist #'identity '(a b c)) ; => ((A B C) (B C) (C))
mapc e mapl sono simili rispettivamente a mapcar e maplist, ma non raccolgono i risultati e restituiscono invece la prima lista.
Si usano per operazioni che hanno effetti collaterali.
mapcan e mapcon sono simili a mapcar e maplist, ma il risultato viene appiattito tramite nconc, che è simile ad append ma è distruttivo su tutti i suoi argomenti tranne l'ultimo.
La mappatura non si limita alle liste. Qualsiasi sequenza (trattata in un altro concetto) può essere mappata.
Nel caso di sequenze che non sono liste, si usa la funzione map.
map accetta 3 o più argomenti:
(map 'list #'double '(1 2 3)) ; => (2 4 6)
(map 'string #'char-upcase "foobar") ; => "FOOBAR"
Come caso speciale, se come tipo della sequenza risultante viene fornito nil, allora viene restituito nil.
Anche questa (come mapc e mapl qui sopra) si usa per gli effetti collaterali.