Объекты-функции замыканий
Скомпилированные в байт-код функции используют специальный тип данных: они являются замыканиями. Замыкания используются как для скомпилированных в байт-код Lisp-функций, так и для интерпретируемых Lisp-функций. Всякий раз, когда такой объект выступает в качестве вызываемой функции, Emacs использует соответствующий интерпретатор для выполнения либо байт-кода, либо нескомпилированного кода Lisp.
Внутри замыкание очень похоже на вектор; к его элементам можно обращаться с помощью aref. Его печатное представление похоже на представление вектора с дополнительным символом ‘#’ перед открывающим ‘[’. Оно должно содержать как минимум три элемента; максимального количества нет, но только первые шесть элементов имеют обычное практическое применение. Это:
- argdesc
-
Дескриптор аргументов. Это может быть либо список аргументов, как описано в разделе Features of Argument Lists, либо целое число, кодирующее требуемое количество аргументов. В последнем случае значение дескриптора определяет минимальное количество аргументов в битах от 0 до 6, а максимальное количество аргументов — в битах от 8 до 14. Если в списке аргументов используется
&rest, бит 7 установлен; в противном случае он сброшен.Когда замыкание представляет собой функцию байт-кода, если argdesc является списком, аргументы будут динамически связаны перед выполнением байт-кода. Если argdesc является целым числом, аргументы вместо этого помещаются в стек интерпретатора байт-кода перед выполнением кода.
- code
-
Для интерпретируемых функций этот элемент представляет собой (непустой) список Lisp-форм, составляющих тело функции. Для функций, скомпилированных в байт-код, это строка, содержащая инструкции байт-кода.
- constants
-
Для скомпилированных в байт-код функций этот элемент содержит вектор Lisp-объектов, на которые ссылается байт-код. К ним относятся символы, используемые в качестве имен функций и имен переменных. Для интерпретируемых функций это
nil, если функция использует старый диалект Emacs Lisp с динамической областью видимости, а в противном случае содержит лексическое окружение функции. - stacksize
-
Максимальный размер стека, необходимый этой функции. Этот элемент не используется для интерпретируемых функций.
- docstring
-
Строка документации (если есть); в противном случае —
nil. Значение может быть числом или списком, если строка документации хранится в файле. Используйте функциюdocumentationдля получения фактической строки документации (см. Access to Documentation Strings). - interactive
Интерактивная спецификация (если есть). Это может быть строка или Lisp-выражение. Имеет значение
nilдля неинтерактивной функции.
Вот пример объекта функции байт-кода в печатном представлении. Это определение команды backward-sexp.
#[256 "\211\204^G^@\300\262^A\301^A[!\207" [1 forward-sexp] 3 1793299 "^p"]
Примитивным способом создания объекта байт-кода является вызов make-byte-code:
- Функция: make-byte-code &rest elements
Эта функция создает и возвращает замыкание, представляющее объект функции байт-кода, элементами которого являются elements.
Не следует пытаться самостоятельно задавать элементы для функции байт-кода, поскольку при их несогласованности Emacs может завершиться с ошибкой при вызове функции. Всегда доверяйте создание таких объектов компилятору байт-кода; он обеспечивает согласованность элементов (как мы надеемся).
Примитивным способом создания интерпретируемой функции является вызов make-interpreted-closure:
- Функция: make-interpreted-closure args body env &optional docstring iform
Эта функция создает и возвращает замыкание, представляющее интерпретируемую функцию с аргументами args и телом body, которое должно быть не-
nilсписком Lisp-форм. env — это лексическое окружение в том же виде, в каком оно используется сeval(см. Eval). Документация docstring, если не равнаnil, должна быть строкой, а интерактивная форма iform, если не равнаnil, должна иметь вид(interactive arg-descriptor)(см. Usinginteractive).
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/Closure-Objects.html