Spec-Zone.ru › Elisp

Анонимные функции

Хотя функции обычно определяются с помощью defun и одновременно получают имена, иногда удобно использовать явное лямбда-выражение — анонимную функцию. Анонимные функции допустимы везде, где допустимы имена функций. Их часто присваивают переменным или передают в качестве аргументов функциям; например, можно передать такую функцию в качестве аргумента function функции mapcar, которая применяет эту функцию к каждому элементу списка (см. Функции отображения). Реалистичный пример этого см. в разделе пример describe-symbols.

Определяя лямбда-выражение, которое будет использоваться как анонимная функция, следует применять макрос lambda, специальную форму function или синтаксис чтения #':

Макрос: lambda args [doc] [interactive] body…

Этот макрос возвращает анонимную функцию со списком аргументов args, строкой документации doc (если она указана), спецификацией интерактивного вызова interactive (если она указана) и формами тела, заданными в body.

Например, этот макрос позволяет формам lambda почти автоматически заключаться в кавычки: вычисление формы, чей CAR — lambda, возвращает значение, почти совпадающее с самой формой:

(lambda (x) (* x x))
     ⇒ #f(lambda (x) :dynbind (* x x))

При вычислении с лексической областью видимости результатом будет похожий объект-замыкание, в котором маркер :dynbind заменён захваченными переменными (см. Замыкания).

У формы lambda есть ещё один эффект: она сообщает интерпретатору Emacs и байт-компилятору, что её аргумент является функцией, используя function в качестве подпрограммы (см. ниже).

Специальная форма: function function-object

Эта специальная форма возвращает функциональное значение function-object. Во многих отношениях она похожа на quote (см. Кавычки). Но, в отличие от quote, она также сообщает интерпретатору Emacs и байт-компилятору, что function-object предназначен для использования в качестве функции. Если предположить, что function-object — допустимое лямбда-выражение, это даёт два эффекта:

  • При байт-компиляции кода function-object компилируется в объект функции в байт-коде (см. Байт-компиляция).
  • Если включена лексическая область видимости, function-object преобразуется в замыкание. См. Замыкания.

Если function-object является символом, а код байт-компилируется, байт-компилятор выдаст предупреждение, если эта функция не определена или может быть неизвестна во время выполнения.

Синтаксис чтения #' — это краткая запись для использования function. Следующие формы эквивалентны:

(lambda (x) (* x x))
(function (lambda (x) (* x x)))
#'(lambda (x) (* x x))

В следующем примере мы определяем функцию change-property, которая принимает функцию в качестве третьего аргумента, а затем функцию double-property, которая использует change-property, передавая ей анонимную функцию:

(defun change-property (symbol prop function)
  (let ((value (get symbol prop)))
    (put symbol prop (funcall function value))))
(defun double-property (symbol prop)
  (change-property symbol prop (lambda (x) (* 2 x))))

Обратите внимание, что мы не заключаем форму lambda в кавычки.

Если скомпилировать приведённый выше код, анонимная функция также будет скомпилирована. Этого бы не произошло, если бы, например, анонимная функция была создана путём заключения её в кавычки как списка:

(defun double-property (symbol prop)
  (change-property symbol prop '(lambda (x) (* 2 x))))

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

Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Anonymous-Functions.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API