13.15 Форма declare

declare — это специальный макрос, который можно использовать для добавления мета-свойств функции или макросу: например, пометки как устаревшей или задания для её форм специального соглашения об отступах по клавише TAB в режиме Emacs Lisp.

Макрос: declare спецификации…

Этот макрос игнорирует свои аргументы и вычисляется в nil; он не имеет эффекта во время выполнения. Однако когда форма declare встречается в аргументе declare определения функции defun или defsubst (см. Определение функций) или определения макроса defmacro (см. Определение макросов), она добавляет свойства, заданные спецификациями, функции или макросу. Эта работа специально выполняется defun, defsubst и defmacro.

Каждый элемент в спецификациях должен иметь вид (свойство аргументы…), который не должен заключаться в кавычки. Они имеют следующие эффекты:

(advertised-calling-convention сигнатура когда)

Это действует как вызов set-advertised-calling-convention (см. Объявление функций устаревшими); сигнатура задаёт правильный список аргументов для вызова функции или макроса, а когда должно быть строкой, указывающей, когда старый список аргументов был впервые объявлен устаревшим.

(debug edebug-спецификация-формы)

Это действительно только для макросов. При пошаговом выполнении макроса с помощью Edebug используйте edebug-спецификацию-формы. См. Инструментирование вызовов макросов.

(doc-string n)

Используется при определении функции или макроса, которые сами будут использоваться для определения сущностей, таких как функции, макросы или переменные. Указывает, что n-й аргумент, если он есть, следует рассматривать как строку документации.

(indent спецификация-отступа)

Оформлять отступы в вызовах этой функции или макроса в соответствии с спецификацией-отступа. Обычно используется для макросов, хотя работает и для функций. См. Отступы в макросах.

(interactive-only значение)

Устанавливает свойство interactive-only функции в значение. См. Свойство interactive-only.

(obsolete текущее-имя когда)

Помечает функцию или макрос как устаревшие, аналогично вызову make-obsolete (см. Объявление функций устаревшими). текущее-имя должно быть символом (в этом случае предупреждение предлагает использовать его вместо старого), строкой (задающей текст предупреждения) или nil (в этом случае предупреждение не содержит дополнительных подробностей). когда должно быть строкой, указывающей, когда функция или макрос были впервые объявлены устаревшими.

(compiler-macro расширитель)

Может использоваться только для функций и указывает компилятору использовать расширитель в качестве оптимизирующей функции. При обнаружении вызова функции вида (функция аргументы…) макро-расширитель вызовет расширитель с этой формой, а также с аргументами…, и расширитель может либо вернуть новое выражение для использования вместо вызова функции, либо вернуть форму без изменений, показывая, что вызов функции следует оставить как есть.

Когда расширитель является лямбда-формой, он должен быть записан с одним аргументом (то есть иметь вид (lambda (арг) тело)), потому что формальные аргументы функции автоматически добавляются к списку аргументов лямбда-выражения.

(gv-expander расширитель)

Объявляет расширитель функцией для обработки вызовов макроса (или функции) как обобщённой переменной, аналогично gv-define-expander. расширитель может быть символом или иметь вид (lambda (арг) тело), в этом случае эта функция будет дополнительно иметь доступ к аргументам макроса (или функции).

(gv-setter установщик)

Объявляет установщик функцией для обработки вызовов макроса (или функции) как обобщённой переменной. установщик может быть символом, в этом случае он будет передан в gv-define-simple-setter, или может иметь вид (lambda (арг) тело), в этом случае эта функция будет дополнительно иметь доступ к аргументам макроса (или функции) и будет передана в gv-define-setter.

(completion предикат-автодополнения)

Объявляет предикат-автодополнения как функцию для определения, включать ли символ функции в список функций при запросе автодополнения в M-x. Эта функция-предикат будет вызываться только если read-extended-command-predicate настроен на command-completion-default-include-p; по умолчанию значение read-extended-command-predicate равно nil (см. execute-extended-command). Предикат предикат-автодополнения вызывается с двумя аргументами: символом функции и текущим буфером.

(modes режимы)

Указывает, что эта команда предназначена для применения только в указанных режимах. См. Указание режимов для команд.

(interactive-args арг ...)

Задаёт аргументы, которые должны сохраняться для repeat-command. Каждый арг имеет вид имя-аргумента форма.

(pure знач)

Если знач не равен nil, эта функция является чистой (см. Что такое функция?). Это то же самое, что свойство pure символа функции (см. Стандартные свойства символов).

(side-effect-free знач)

Если знач не равен nil, эта функция не имеет побочных эффектов, поэтому байт-компилятор может игнорировать вызовы, значение которых игнорируется. Это то же самое, что свойство side-effect-free символа функции, см. Стандартные свойства символов.

(important-return-value знач)

Если знач не равен nil, байт-компилятор выдаст предупреждение о вызовах этой функции, в которых не используется возвращаемое значение. Это то же самое, что свойство important-return-value символа функции, см. Стандартные свойства символов.

(speed n)

Задаёт значение native-comp-speed, действующее для нативной компиляции этой функции (см. Переменные нативной компиляции). Это позволяет управлять уровнем оптимизации для нативного кода, генерируемого для функции, на уровне самой функции. В частности, если n равно −1, нативная компиляция функции выдаст байт-код вместо нативного кода для этой функции.

(safety n)

Задаёт значение compilation-safety, действующее для этой функции. Это позволяет управлять уровнем безопасности для кода, генерируемого для функции, на уровне самой функции (см. Переменные нативной компиляции).

(ftype тип &optional функция)

Объявляет тип как тип этой функции. Этот тип используется describe-function для документации, а также нативным компилятором (см. Компиляция Lisp в нативный код) для оптимизации генерации кода и вывода типов. Неправильные объявления типов могут вызывать сбои в нативно скомпилированном коде (см. ниже). Функции с объявлениями типов отображаются в C-h C-f как имеющие объявленный тип, в отличие от выведенного типа для функций без них.

тип — это спецификатор типа (см. Спецификаторы типов) вида (function (тип-арг-1 … тип-арг-n) ТИП-ВОЗВРАТА). Типы аргументов могут перемежаться с &optional и &rest для отражения соглашения о вызове функции (см. Особенности списков аргументов).

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

Вот пример использования ftype внутри declare для определения функции positive-p, которая принимает аргумент типа число и возвращает логическое значение:

(defun positive-p (x)
  (declare (ftype (function (number) boolean)))
  (when (> x 0)
    t))

Аналогично, это определяет функцию cons-or-number, которая принимает первый аргумент типа cons или число, второй необязательный аргумент типа строка и возвращает один из символов is-cons или is-number:

(defun cons-or-number (x &optional err-msg)
  (declare (ftype (function ((or cons number) &optional string)
			    (member is-cons is-number))))
  (if (consp x)
      'is-cons
    (if (numberp x)
	'is-number
      (error (or err-msg "Непредвиденный ввод")))))

Описание дополнительных типов см. в Типы данных Lisp.

Объявление функции с неправильным типом приводит к неопределённому поведению. Если такая функция компилируется нативно с compilation-safety, установленным в ноль (см. compilation-safety), это может привести к неправильному выполнению или даже к падению Emacs при загрузке скомпилированного кода. Переопределение или советование функции с объявленным типом должно сохранять исходную сигнатуру во избежание этих проблем.

no-font-lock-keyword

Это действительно только для макросов. Макросы с этим объявлением подсвечиваются font-lock (см. Режим Font Lock) как обычные функции, а не специально как макросы.