Недавно я коснулся elisp и попытался понять, как работает макрос elisp. Учебник GNU содержит глава Surprising-local-Vars для локальной переменной макроса, и я не понимаю, как работает расширение макроса.
(defmacro for (var from init to final do &rest body)
"Execute a simple for loop: (for i from 1 to 10 do (print i))."
(let ((tempvar (make-symbol "max")))
`(let ((,var ,init)
(,tempvar ,final))
(while (<= ,var ,tempvar)
,@body
(inc ,var)))))
Есть две формы let. первый
(let ((tempvar (make-symbol "max")))
не имеет обратной кавычки, которая будет оцениваться во фразе расширения макроса, поэтому неинтернированный символ «max» будет создан только в этой фразе. И неинтернированный символ "max" потеряется во время выполнения, он не должен работать правильно?
Но на самом деле работает хорошо. Я пробовал следующее:
(for max from 1 to 10 do (print max))
И его расширение следующим образом:
(macroexpand '(for max from 1 to 10 do (print max)))
(let ((max 1) (max 10)) (while (<= max max) (print max) (setq max (+ 1 max))))
Здесь два максимальных символа, один привязан к 1, другой привязан к 10, выражение формы while имеет два максимальных символа.
(while (<= max max)
как форма while разрешает два разных символа «max»?