From: Thomas A. Russ on
pjb(a)informatimago.com (Pascal J. Bourguignon) writes:

> Here, the rule that applies, is that a form which is a list, is
> interpreted depending on the first element of that list. The meaning
> of:
>
> ((SETF #:G3813 NIL) X Y Z)
>
> depends on what (SETF #:G3813 NIL) is.
>
> ...
> But here, it is a list starting with the
> symbol CL:SETF, so it won't do.

This is actually a bit interesting, because there is some disconnect
between what is actually a function designator and what can be used in
the function position of various constructs.

So, for example, one can use (setf <name>) as the name of a function for
use in the FUNCTION, #' and DEFUN constructs, but it isn't really a
first-class function designator, because it can't be used as the first
element of a list.

To use a silly example, one could write something like

(defstruct pair
one two)

(defun (setf both) (value place)
(setf (pair-one place) value)
(setf (pair-two place) value))

And then it would be possible to do

(defvar *s* (make-pair))

(setf (both *s*) 10)
*s* => #S(PAIR :ONE 10 :TWO 10)

One could even do the following:

(funcall #'(setf both) 20 *s*)
*s* => #S(PAIR :ONE 20 :TWO 20)

but it would not be legal to try

((setf both) 20 *s*)

I wonder if part of this was because of the fairly late addition of the
(setf <name>) syntax as a function name to DEFUN and FUNCTION that made
this not be more universal. In some ways it seems like it should
logically behave a lot more like LAMBDA.

--
Thomas A. Russ, USC/Information Sciences Institute
From: Alex Mizrahi on
TAR> So, for example, one can use (setf <name>) as the name of a function
TAR> for use in the FUNCTION, #' and DEFUN constructs, but it isn't really
TAR> a first-class function designator, because it can't be used as the
TAR> first element of a list.

I find it interesting how (setf (both ..)..) gets macroexpanded, in SBCL:

CL-USER> (macroexpand '(setf (both *s*) 10))

(LET* ((#:G3082 *S*))
(MULTIPLE-VALUE-BIND (#:G3081) 10 (FUNCALL #'(SETF BOTH) #:G3081
#:G3082)))
T


So CL implementation can't use (SETF BOTH) as function name and has to use
FUNCALL because of that. That's pretty ugly.
I guess SBCL recognizes the case when FUNCALL's parameter is a constant and
it can still generate correct code, but it doesn't look right, as for me.