有人可以帮我理解如何push
实现为宏吗?下面的朴素版本对位置形式进行了两次评估,并且在评估元素形式之前这样做:
(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
在不评估两次的情况下找到正确的地方?