Одним из основных типов функционалов являются функции, которые позволяют вызывать другие функции, иными словами, применять функциональный аргумент к его параметрам. Такие функционалы называют применяющими или аппликативными функционалами.
Применяющие функционалы родственны универсальной функции Лиспа eval. В то время как eval вычисляет значение произвольного выражения (формы), применяющий функционал вычисляет значение вызова некоторой функции. Интерпретатор Лиспа eval и на самом деле вызывает применяющий функционал apply при вычислении вызова, а apply в свою очередь вызывает eval при вычислении значения других форм.
Применяющие функционалы дают возможность интерпретировать и преобразовывать данные в программу и применять её в вычислениях.
apply является (в своей исходной форме) функцией двух аргументов, из которых первый аргумент представляет собой функцию, которая применяется к элементам списка, составляющим второй аргумент функции apply:
(nil apply obj fn список)
≡
(obj fn 'x1 'x2 … 'xn),
где список=(x1 x2 … xn)
>(nil apply 2 '+ '(3))
5
>(nil apply nil 'cons '(что (пожелаете)))
(что пожелаете)
>('f set '+)
+
>(nil apply 2 f '(3))
5
>(nil apply nil 'eval '((2 + 3)))
5
>(nil apply nil 'apply '(2 + (3))) ; apply применяет себя
5
>(nil apply nil '(lambda (x y) (x + y)) '(2 3))
5
Использование apply даёт большую гибкость по сравнению с прямым вызовом функции: с помощью одной и той же функции apply можно в зависимости от функционального аргумента осуществлять различные вычисления.
Функционал funcall по своему действию аналогичен apply, но аргументы для вызываемой функции он принимает не списком, а по отдельности:
(nil funcall obj fn x1 x2 … xn)
≡
(obj fn x1 x2 … xn)
Приведём пример:
>(nil funcall 2 '+ 3)
5
funcall и apply позволяют задавать вычисления (функцию) произвольной формой, например, как в вызове функции, или символом, значением которого является функциональный объект. В обыкновенном вызове функции можно использовать лишь символ, связанный defmethod с лямбда-выражением. Интерпретация имени зависит от синтаксической позиции.
>('сложение set '+)
+
>(nil funcall 2 сложение 3)
5
>(nil funcall 2 ('(+ - * /) first) 3)
5
Таким образом появляется возможность использовать синонимы имени функции. С другой стороны, имя функции можно использовать как обыкновенную переменную, например для хранения другой функции (имени или лямбда-выражения), и эти два смысла (значение и определение) не будут мешать друг другу:
>('cons set '+)
+
>(nil funcall 2 cons 3)
5
>(nil cons 2 3)
(2 . 3)
Поскольку второй аргумент функционала funcall вычисляется по обыкновенным правилам, то на его месте должно стоять выражение, значением которого будет символ или лямбда-выражение.