Common Lisp, reference to value and actual value

后端 未结 2 1514
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-23 17:22

Consider this piece of code:

(defvar lst \'(1 1))

(defmacro get-x (x lst)
  `(nth ,x ,lst))

(defun get-y (y lst)
  (nth y lst))

Now let us as

2条回答
  •  醉话见心
    2021-01-23 17:31

    The error does not happen with the macro version, because, as you assumed, the expression (setf (get-x some-x some-list) some-value) will be expanded (at compile-time) into something like (setf (nth some-x some-list) some-value) (not really, but the details of setf-expansion are complex), and the compiler knows, how to deal with that (i.e., there is a suitable setf expander defined for function nth).

    However, in the case of get-y, the compiler has no setf expander, unless you provide one. The easiest way to do so would be

    (defun (setf get-y) (new-value x ls)    ; Note the function's name: setf get-y 
        (setf (nth x ls) new-value))
    

    Note, that there are a few conventions regarding setf-expanders:

    1. The new value is always provided as the first argument to the setf function
    2. All setf functions are supposed to return the new value as their result (as this is, what the entire setf form is supposed to return)

    There is, BTW, no such concept as a "reference" in Common Lisp (at least not in the C++ sense), though there once were Lisp dialects which had locatives. Generalized place forms (ie., setf and its machinery) work very differently from plain C++ style references. See the CLHS, if you are curious about the details.

提交回复
热议问题