Введение в программирование на Лиспе

         

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


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

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

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

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

( lambda (x1 ... xK) expr )

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

(defun sqware (xl)(map-el(lambda(x)(* x x))xl)) (defun duble (xl)(map-el(lambda(x)(cons x x))xl))

Пример 7.9. Определение функций duble и sqwure из примеров 4 и 5 без использования имен и вспомогательных функций: (html, txt)

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



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