Анонимные функции
Хотя функции обычно определяются с помощью 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