push
誰かがマクロとして実装する方法を理解するのを手伝ってもらえますか?以下の単純なバージョンは、場所のフォームを2回評価し、要素のフォームを評価する前に評価します。
(defmacro my-push (element place)
`(setf ,place (cons ,element ,place)))
しかし、これを以下のように修正しようとするとsetf
、間違った場所に移動します:
(defmacro my-push (element place)
(let ((el-sym (gensym))
(place-sym (gensym)))
`(let ((,el-sym ,element)
(,place-sym ,place))
(setf ,place-sym (cons ,el-sym ,place-sym)))))
CL-USER> (defparameter *list* '(0 1 2 3))
*LIST*
CL-USER> (my-push 'hi *list*)
(HI 0 1 2 3)
CL-USER> *list*
(0 1 2 3)
setf
2回評価せずに正しい場所を設定するにはどうすればよいですか?