Анонимные функции
Хотя функции обычно определяются с помощью defun и получают имена одновременно, иногда удобно использовать явное лямбда-выражение — анонимную функцию. Анонимные функции допустимы везде, где допустимы имена функций. Они часто присваиваются в качестве значений переменных или как аргументы функциям; например, вы можете передать её как аргумент function к mapcar, которая применяет эту функцию к каждому элементу списка (см. Функции отображения). См. пример describe-symbols для реального примера этого.
При определении лямбда-выражения, которое будет использоваться как анонимная функция, вы в принципе можете использовать любой метод для построения списка. Но обычно вы должны использовать макрос lambda, или специальную форму function, или синтаксис чтения #':
- Макрос: lambda args [doc] [interactive] body…
-
Этот макрос возвращает анонимную функцию со списком аргументов args, строкой документации doc (если есть), спецификацией интерактивного режима interactive (если есть) и формами тела, заданными body.
При динамической связи этот макрос эффективно делает
lambdaформы самоцитируемыми: вычисление формы, у которой CAR являетсяlambda, возвращает саму форму:(lambda (x) (* x x)) ⇒ (lambda (x) (* x x))Обратите внимание, что при вычислении с лексической связью результатом является объект замыкания (см. Замыкания).
Форма
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-2022 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Anonymous-Functions.html