Не могли бы вы объяснить различия между тремя символами: proclaim
, declaim
и declare
?
Провозгласить, объявить, объявить
Ответ 1
Это символы, а не ключевые слова.
-
proclaim
имена функций для создания глобальных объявлений. Вы должны использоватьdeclaim
вместо этого, когда это возможно. -
declaim
называет макрос для создания глобальных объявлений (например,proclaim
), которые также эффективны во время компиляции. -
declare
- это просто символ (например, он не называет функцию, макрос или специальный оператор) для создания локальных объявлений в начале некоторых форм (вы можете рассматривать его как элемент синтаксиса этих форм).
Итак, первые два влияют на глобальную среду, а последний - локальный.
declaim
proclaim
предпочтительнее, чем proclaim
поскольку он оказывает непосредственное влияние на среду компиляции:
Хотя исполнение в
proclaim
форму имеет последствие, которые могут повлиять на компиляцию, компилятор не делает никаких попыток признать и специально процесс провозглашает форму. Прокламация, такая как следующее, даже если форма верхнего уровня, не имеет никакого эффекта, пока не будет выполнена:
(proclaim '(special *x*))
Если желательны побочные эффекты времени компиляции, может быть полезно
eval-when
. Например:
(eval-when (:execute :compile-toplevel :load-toplevel) (proclaim '(special *x*)))
Однако в большинстве таких случаев для этой цели предпочтительнее использовать
declaim
.
Т.е. если твой код
(proclaim '(special *x*))
(defun foo () (print *x*))
компилятор будет жаловаться, что foo
читает неизвестную специальную переменную *x*
, в то время как
(declaim (special *x*))
(defun foo () (print *x*))
не вызовет никаких предупреждений.
PS Если вы задаетесь вопросом, почему CL имеет даже proclaim
: первый, исторически это было там до declaim
, и, во- вторых, proclaim
проще и полезнее в макросах.