Подтвердить что ты не робот

Общий Lisp Связывание в макросе цикла

Я хочу перепрограммировать специальную переменную внутри цикла. Теперь, как правило, это выполняется с помощью let.

(let ((*read-eval* nil))
  (do-something-here))

Но так как макрос loop имеет эти приятные предложения with, я думал, что смогу сделать это там. Выражение (macroexpand '(loop with *read-eval* = nil)) заканчивается расширением привязки к let, поэтому он определенно будет работать над моей реализацией. Но я не могу найти что-либо в стандарт, указывающий, что это стандартизованное поведение. Итак, я полагаю, мой вопрос таков:

(loop with *read-eval* = nil
      for i from 1 to 10
      do (something-involving-the-read-function))

Соответствуют ли реализации, необходимые для изменения существующей переменной *read-eval*, или существует риск того, что они могут создать новую лексическую переменную с тем же именем?

4b9b3361

Ответ 1

*read-eval* - глобальная специальная переменная. Невозможно отменить это, т.е. Создать для него локальную лексическую привязку.

with статья описывается как использование привязок (в отличие от простой настройки), что означает, что, как только цикл будет завершен, мы вернемся к исходному значению (чтобы ответить на вопрос @joshua-tailor).

Давайте рассуждать рационально. (loop with foo = nil ...) определенно устанавливает привязку для foo. Таким образом, для (loop with *read-eval* = nil ...) не устанавливать эту привязку, реализация должна проверять (при макрорасширении или времени компиляции), будет ли *read-eval* динамической переменной во время выполнения. Это звучит безумно.