Функции более высокого порядка

Функционал имеет функциональный аргумент

  До сих пор мы рассматривали функции, которые в качестве аргументов получали формы, представляющие собой выражения, являющиеся данными. Значения функций также считались относящимися по типу к данным, т.е. выражениям, трактуемым как данные.
  Основываясь на едином представлении данных и программ, функции в качестве аргумента можно указать и функцию, или, другими словами, определение функции, либо представляющий функцию символ. Аргумент, значением которого является функция, называют в функциональном программировании функциональным аргументом, а функцию, имеющую функциональный аргумент - функционалом.
  Различие между понятиями "данные" и "функция" определяется не на основе их структуры, а в зависимости от их использования. Если аргумент используется в функции лишь как объект, участвующий в вычислениях, то мы имеем дело с обыкновенным аргументом, представляющим данные. Если же он используется как средство, определяющее вычисления, т.е. играет в вычислениях, например, роль лямбда-выражения, которое применяется к другим аргументам, то мы имеем дело с функцией.
  Одно и то же выражение может в связи с различными аспектами выступать, с одной стороны, как обыкновенный аргумент, а с другой стороны, как функциональный. Роль и интерпретация выражения зависят от его синтаксической позиции. Приведём пример:

>('(lambda () (nil list this)) first) ; first - функция
lambda ; лямбда-выражение - данные
>('first (lambda () (nil list this))) ; first - данные
(first) ; лямбда-выражение - функция

  Переданное функции first лямбда-выражение не является функциональным аргументом, и first не становится функционалом. То же самое лямбда-выражение, стоящее в позиции функции, уже интерпретируется как функция в то время, как first интерпретируется как данные. Функциональный аргумент и функционал являются некоторым обобщением простого понятия функции: функциональным аргументом может быть любой подходящий объект, который используется в теле функционала в позиции функции и в роли функции.
  Далее мы будем использовать понятия функции, вызова функции и значения функции в следующем смысле:

  1. Функция сама есть изображение вычислений или определение.
  2. Вызов функции есть применение этого изображения.
  3. Значение функции есть результат такого применения.

  Функция является функционалом, если в качестве её аргумента используется лисповский объект типа, который интерпретируется как функция в теле функционала. Таким функциональным объектом может быть символьное имя, представляющее определение функции (системная функция или функция, определённая пользователем) или безымянное лямбда-выражение.
  Фактический параметр для функционального аргумента функционала задаётся в виде формы, значением которой будет объект, который можно интерпретировать как функцию. Приведём примеры:

'(lambda () (nil list this))
(nil list 'lambda nil (nil list nil 'list 'this))
('(first rest cons) first)

Функциональное значение функции

  Аргументом функции может быть функция, однако, функция может быть и результатом. Такие функции называют функциями с функциональным значением. Функционал также может быть с функциональным значением. Вызов такого функционала возвращает в качестве результата новую функцию, в построении которой, возможно, используются функции, получаемые функционалом в качестве аргументов. Такие функционалы мы будем называть функционалами с функциональным значением.
  Для запуска функции, которая получается результатом функционала, можно использовать функцию eval или макросы.
  Представленные функционалы и функции с функциональным значением в отличие от обыкновенных функций, получающих в качестве аргументов и возвращающих в качестве значения данные или выражения, значением которых являются данные, называются функциями более высокого порядка. Обыкновенные функции независимо от того, рекурсивные они или нет, являются функциями первого порядка.
  Функции более высокого порядка открывают новые возможности для программистов, позволяя сложные вычисления записывать более коротко. Многие вещи, которые в традиционных языках или при традиционном подходе трудно или практически невозможно запрограммировать, можно определить яснее и короче, используя различные типы функционалов и функции с функциональным значением.
  Передача функции в качестве параметра другой функции и создание функции с помощью специальных форм составляет основу для новых технологий программирования, таких, например, как программирование, управляемое данными, и объектно-ориентированное программирование. Функции более высокого порядка тесно связаны с объектами и макросами, а также с частичными и отложенными вычислениями.
  Функции более высокого порядка тесно связаны с абстрактными понятиями и отображениями. Теоретическое и практическое владение ими предполагает умение учитывать типы функций, т.е. учитывать типы принимаемых ими аргументов и возвращаемых ими значений.