Применяющие функционалы

  Одним из основных типов функционалов являются функции, которые позволяют вызывать другие функции, иными словами, применять функциональный аргумент к его параметрам. Такие функционалы называют применяющими или аппликативными функционалами.
  Применяющие функционалы родственны универсальной функции Лиспа eval. В то время как eval вычисляет значение произвольного выражения (формы), применяющий функционал вычисляет значение вызова некоторой функции. Интерпретатор Лиспа eval и на самом деле вызывает применяющий функционал apply при вычислении вызова, а apply в свою очередь вызывает eval при вычислении значения других форм.
  Применяющие функционалы дают возможность интерпретировать и преобразовывать данные в программу и применять её в вычислениях.

APPLY применяет функцию к списку аргументов

  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 вызывает функцию с аргументами

  Функционал 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 вычисляется по обыкновенным правилам, то на его месте должно стоять выражение, значением которого будет символ или лямбда-выражение.