Paul Grahams 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)
編輯:這是一個解決方案,其中變量保存,然後恢復(使用下面的finnw提示)。但是在Vatine的答案中隱藏變量可能更優雅。
(defmacro save-run (varlist &body body)
`(let ((valuelist (list ,@varlist)))
,@body
(multiple-value-setq ,varlist (values-list valuelist))))
您不需要'(progn,@ body)'。只是',@ body'會有同樣的效果。 – finnw
如果你使用'(setf(values,@ varlist)...)'而不是'(multiple-value-setq,varlist ...)',那麼一些變量可以是符號以外的地方,例如, '(save-run((cdr x))...)' – finnw
不確定你在這裏是什麼意思。我查看了文檔,並且setf只能成對分配偶數個參數,而不是列表。 – snowape