ポール・グラハムズの練習の1つ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)
編集:ここで、変数が保存され、復元されるソリューションです(以下のヒントを参考にしてください)。しかし、Vatineの答えのように変数をシャドーイングする方がおそらくもっとエレガントです。
(defmacro save-run (varlist &body body)
`(let ((valuelist (list ,@varlist)))
,@body
(multiple-value-setq ,varlist (values-list valuelist))))
'(progn、@ body)'は必要ありません。 '、@ body'と同じ効果があります。 – finnw
'(multiple-value-setq、varlist ...)の代わりに'(setf(values、@ varlist)...) 'を使うと、変数のいくつかはシンボル以外の場所にすることができます。 '(save-run((cdr x))...)' – finnw
あなたがここで何を意味するのか分かりません。私はドキュメントを見て、setfはリストではなく、ペアで割り当てられた偶数の引数しか取ることができません。 – snowape