Важный класс функционалов в практическом программировании на языке Лисп образуют отображающие функции или map-функции (mapping function). Map-функционалы являются функциями, которые некоторым образом отображают (map) список (вектор) в новый элемент или порождают побочный эффект. Вызов map-функции имеет вид:
(obj-seq map fn argseq1 … argseqn)
Здесь obj-seq argseq1 … argseqn - списки (вектора), а fn - функция от n аргументов. Как правило, map-функция применяется к функции без аргументов.
(obj-seq map fn)
Результатом этих вычислений будет список (вектор), состоящий из результатов применения функции. Все вычисления производятся параллельно. Например, в случае одного списка объектов получается следующее соответствие:
('(x1 x2 … xn) map fn)
≡
(nil list ('x1 fn) ('x2 fn) … ('xn fn))
В качестве значения функционала возвращается список, построенный из результатов вызовов функционального аргумента map. Приведём пример:
>('l set '(1 2 3))
(1 2 3)
>(l map 'oddp)
(1 false 3)
>(l map '(lambda () (nil list (nil progn (cout writeln this) this))))
2
1 ; параллельное исполнение
3
((1) (2) (3))
>(nil defmethod pair () (nil list this 'x))
(lambda () (nil list this 'x))
>(l map 'pair)
((1 x) (2 x) (3 x))
Использованные выше функции (oddp, pair) были функциями без аргументов, т.е. каждый раз они имеют дело с одним элементом. Если бы функции map был передан функциональный аргумент fn с большим количеством параметров, то и у map-функционала было бы соответствующее количество параметров-списков.
В приведённом ниже вызове, например, функциональным аргументом map является функция cons, которая требует двух аргументов. Вызов map строит список пар из соответствующих элементов двух просматриваемых списков:
>(l map '(lambda (x) (nil cons this x)) '(a b c)) ((1 . a) (2 . b) (3 . c)) >(#(1 2 3) map '(lambda (x) (nil list this x)) #(a b c)) #((1 a) (2 b) (3 c))
map можно определить через используемый в Лиспе применяющий функционал. Для случая функционального аргумента без параметров функция map выглядела бы следующим образом:
(nil defmethod map (fn)
(nil if (nil consp this)
(nil cons (nil funcall (this first) fn)
((this rest) map fn))))
Функционал map используется для программирования циклов специального вида и в определении других функций, поскольку с их помощью можно сократить запись повторяющихся вычислений.
Функция mapc также аналогична функции map, но отличается тем, что не собирает и не объединяет результаты. Возникающие результаты просто теряются. Псевдофункционал mapc прежде всего используют для получения побочного эффекта.