Одним из упражнений в книге Пола Грэхама ANSI Common Lisp является следующее: Определите макрос, который принимает список переменных и тело кода и гарантирует, что переменные вернутся к своим исходным значениям после того, как тело кода будет оценено.
Проблема, с которой я столкнулся в этом упражнении, заключается в том, как сохранить имена символов входных переменных. Ниже у меня есть начало, где я сохраняю только те значения, к которым привязаны символы.
(defmacro save-run (varlist &body body)
`(let ((valuelist (list ,@varlist)))
(format t "valuelist: ~A" valuelist)))
(let ((a 5)(b 6))
(values '(a b))
(save-run (a b)
(setf a 7)
(setf b 8)))
[507]> valuelist: (5 6)
Edit: вот решение, в котором переменные сохраняются, а затем восстанавливаются (используя советы из finnw ниже). Но затенение переменных, как в ответе Ватина, возможно, более элегантно.
(defmacro save-run (varlist &body body)
`(let ((valuelist (list ,@varlist)))
,@body
(multiple-value-setq ,varlist (values-list valuelist))))