Основы функционального программирования


Безымянные функции


Определения в примерах 4.4 и 4.5 не вполне удобны по следующим причинам:

  • в определениях целевых функций duble и sqware встречаются имена специально определенных вспомогательных функций;
  • формально эти функции независимы, значит, программист должен отвечать за их наличие при использовании целевых функций на протяжении всего жизненного цикла программы, что трудно гарантировать;
  • вероятно, имя вспомогательной функции будет использоваться только один раз - в определении целевой функции.

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

Учитывая это, было бы удобнее вспомогательные определения вкладывать непосредственно в определения целевых функций и обходиться при этом вообще без имен. Конструктор функций lambda обеспечивает такой стиль построения определений. Этот конструктор любое выражение expr превращает в функцию с заданным списком аргументов (x1. .. xK) в форме так называемых lambda-выражений:

(lambda (x1 ... xK) expr)

Имени такая функций не имеет, поэтому может быть применена лишь непосредственно. DEFUN использует данный конструктор, но требует дать функциям имена.

Определение функций duble и sqware из примеров 4.4 и 4.5 без использования имен и вспомогательных функций:

(defun sqware (xl) (map-el #' (lambda (x) (* x x)) xl))

(defun duble (xl) (map-el #' (lambda (x) (cons x x)) xl))

Пример 4.9.

Любую систему взаимосвязанных функций можно преобразовать к одной функции, используя вызовы безымянных функций.



Содержание раздела