Предупреждение дает мало значения. Переменная связана с предыдущим присвоением верхнего уровня, которое создает привязку в глобальной среде , делая эту переменную глобальной переменной. Это просто доступ, что, скорее всего, и предусмотрено программистом.
Предупреждение о несвязанной переменной очень ценно, когда не определено определение переменной, потому что оно перехватывает орфографические ошибки ссылок на переменные. Но реализация setf
или setq
верхнего уровня должна быть замечена реализацией и рассматриваться как определение.
Полезно иметь предупреждение для случаев, когда переменная определена верхним уровнем setf
, а затем в зависимости от let
:
(setf n 42)
(let ((n 43)) (func))
Здесь, похоже, программист ожидал, что n
будет специальной переменной, но она не была определена таким образом. func
увидит привязку верхнего уровня n
, которая содержит 42, а не лексическую n
, которая содержит 43. Так что есть веская причина для диагностики здесь. Цель кода требует, чтобы n
было объявлено с помощью defvar
или defparameter
, или объявлено специальным.
(Конечно, мы не можем предупредить о (let ((n 43)) ...)
, когда не было замечено ни одного верхнего уровня n
, потому что это обычная ситуация для подавляющего большинства лексических переменных.)
В ANSI Common Lisp есть некоторый недостаток, заключающийся в том, что в разделе 3.1.2.1.1 Символы в виде форм говорится, что существует только три типа переменных: динамические, лексический и постоянный. Динамическая переменная - это переменная, объявленная особой, и поэтому в соответствии с этим рассуждением setf
недостаточно для создания динамической переменной. Однако в разделе 3.1.1.1 четко указано, что существует глобальная среда. Смущает, что он говорит, что он содержит привязки, которые имеют неопределенный размер и область действия, и что он содержит динамические переменные. Но тогда «динамическая переменная» определяется в глоссарии как переменная с привязкой в динамической среде, а динамическая среда определяется как содержащая привязки с «динамическим экстентом». Так что это не может быть глобальной средой. Вы знаете, что тот, который говорит 3.1.1.1, содержит динамические переменные!
Как бы то ни было, вся эта путаница в ANSI породила неправильное представление о том, что setf
или setq
не может создать переменную, которая поддерживает ложную диагностику компилятора.