有人可以幫我理解push
可以作爲一個宏來實現嗎?下面的幼稚版本評估地方形式兩次,評估元素形式之前這樣做:我怎樣才能實現推宏?
(defmacro my-push (element place)
`(setf ,place (cons ,element ,place)))
但是,如果我嘗試如下解決這個問題,然後我setf
-ing錯了地方:
(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
正確的地方沒有評估兩次?
回頭看看SBCL源代碼,我發現他們使用一次性宏來處理rplaca(請參閱此鏈接瞭解更多信息http://stackoverflow.com/questions/9808928/understanding-how-to-implement-once -only-lisp-macro)。我會調查rplaca進一步瞭解。 – 2012-08-07 22:43:08
@PaulNathan您能否提供您正在查看的SBCL版本和源位置?因爲我在'src/code/early-setf.lisp'(SBCL 1.0.58)中看到'(defmacro-mundanely push(obj place&environment env)...',它沒有使用'once-only'。 – 2012-08-08 07:27:46