setf

setf

setf

(defclass foo ()

((foo-slot-1 :accessor foo-slot-1)))



(defparameter *a-foo* (make-instance 'foo))

(macroexpand-1 '(setf (foo-slot-1 *a-foo*) 99))

(let* ((#:temp1 *a-foo*))

(multiple-value-bind (#:temp0)

99

(funcall #'(setf foo-slot-1) #:temp0 #:temp1)))

;; i.e., (funcall #'(setf foo-slot-1) 99 *a-foo*)

#'(setf foo-slot-1)

funcall

funcall function &rest args => result*

function---a function designator.



function designator n. a designator for a function; that is, an object that denotes a function and that is one of: a symbol (denoting the function named by that symbol in the global environment), or a function (denoting itself). The consequences are undefined if a symbol is used as a function designator but it does not have a global definition as a function, or it has a global definition as a macro or a special form. See also extended function designator.



#'(setf a)

extended function designator n. a designator for a function; that is, an object that denotes a function and that is one of: a function name (denoting the function it names in the global environment), or a function (denoting itself). The consequences are undefined if a function name is used as an extended function designator but it does not have a global definition as a function, or if it is a symbol that has a global definition as a macro or a special form. See also function designator.



function name n. 1. (in an environment) A symbol or a list (setf symbol) that is the name of a function in that environment. 2. A symbol or a list (setf symbol).



setf function n. a function whose name is (setf symbol).



setf function name n. (of a symbol S) the list (setf S).



(setf symbol)

setf foo-slot-1)

setf

funcall

#'

#'(setf foo-slot-1)

(function (setf foo-slot-1))

(setf foo-slot-1)

function

#'(setf foo-slot-1)

#

(funcall #(setf symbol) newvalue oldvalue)

5.1.2.9 Other Compound Forms as Places



For any other compound form for which the operator is a symbol f, the setf form expands into a call to the function named (setf f). The first argument in the newly constructed function form is newvalue and the remaining arguments are the remaining elements of place. This expansion occurs regardless of whether f or (setf f) is defined as a function locally, globally, or not at all. For example,



(setf (f arg1 arg2 ...) new-value)



expands into a form with the same effect and value as

(let ((#:temp-1 arg1) ;force correct order of evaluation

(#:temp-2 arg2)

...

(#:temp-0 new-value))

(funcall (function (setf f)) #:temp-0 #:temp-1 #:temp-2...)) A function named (setf f) must return its first argument as its only value in order to preserve the semantics of setf.

(setf (mumble object :keyword1 :keyword2) newvalue)

(funcall #'(setf mumble) newvalue :keyword1 :keyword2)

setf

huge

Yesterday I wanted to wrap a library'smethod in anothermethod that I was writing, but I wasn't sure how to directly call the other library'smethod.Say I have the following:Then if I macroexpand the call to (using SBCL):I get the following (with some cleaning up of the gensyms):That function argumentlooks pretty strange, so I tried finding out what is going on here.After a lot of research, here's what I found.From the HyperSpec,has the following syntax:The glossary entry for 'function designator' isn't too helpfulSinceis clearly not a symbol, it must be a function, but that's certainly a weird way to designate a function.The entry for "extended function designator" isn't by itself any more useful, but provides a small clue:The key here is "function name":Additionally, there's also these entries:Aha! So the only two ways to specify a function name is with a symbol (the case we're all familiar with) or the listSo, we're pretty close. The list (is afunction name. You'll note thattakes a function designator and not an extended function designator, that is, it takes functions, not function names. Of course, the way to get from function names to functions is to use the function "function" or the better know reader macro. Thus, we finally have, which is equivilent to(no quote needed forbecauseis a special operator. So, if you type, you'll get back something likeThe final oddity is the ordering of the arguments, it appears to beThis is explained in the sections explaining how setf expansion works:Putting the new value first allows everything following to look just like the call to the accessing function, even if it has lots of additional lambda keyword arguments, for examplebeing transformed into something likeAnyway, I was able to successfully call the other library'smethod by following the above example.My final thoughts, I have aamount of respect for the people able to read between the lines of the spec and be able to correctly implement all of the nooks and crannies of Common Lisp.