[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: setf order of evaluation
Date: Fri, 11 Sep 87 14:44 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: Thu, 10 Sep 87 23:13 EDT
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
...
;; #2: The case in question (using a non-variable as a place)
(PROGN (SETQ R '(A 1 B 2 C 3))
(SETQ S R)
(SETF (GETF (NTHCDR 2 R) 'B) (PROGN (SETQ R NIL) 6))
(VALUES R S))
...
;; #2a: doesn't use GETF at all
(PROGN (SETQ R '(A 1 B 2 C 3))
(SETQ S R)
(SETF (NTHCDR 2 R) (PROGN (SETQ R NIL) 6))
(VALUES R S))
which again blows up with CLtL's setf-method for variables, but does
what one would expect with the one I suggested. These two examples
changed my mind; now I think the one I suggested is obviously right,
and the one in CLtL, evidently used by Symbolics and Lucid (and no
doubt other implementations) is obviously wrong.
Minor point: NTHCDR is not a standard generalized variable in CLtL.
Major point: Does the following example change your mind back?
(PROGN (SETQ R (LIST (LIST A 1 B 2 C 3)))
(SETQ S (CAR R))
(SETF (GETF (CAR R) 'B) (PROGN (SETF (CAR R) NIL) 6))
(VALUES R S))
I'll bet that SCL currently returns
(A 1 B 2 C 3) ; ((B 6))
regardless of variable setf-method used. But it should return
(A 1 B 6 C 3) ; (NIL)
As JonL (I think) implicitly pointed out, it is the responsibility of GETF to
evaluate the access-form of the sub-setf-method (e.g., (CAR G0001)).
It is NOT the responsibility of the sub-setf-method. Otherwise the
setf-method for (CAR exp) would have to look like
(G0001 G0002)
(exp (CAR G0001))
(G0003)
(PROGN (RPLACA G0001 G0003) G0003)
G0002
Here's another GETF puzzle (only for implementations that did the
right thing above):
(PROGN (SETF S (LIST (LIST A 1 B 2 C 3)))
(SETF R (CAR S))
(SETF (GETF (CAR S) 'D) (PROG1 4 (SETF (CAR S) NIL)))
(VALUES R S))
could legally return:
#1=(A 1 B 2 C 3) ; (D 4 . #1#) {if new pairs are added to the front}
(A 1 B 2 C 3 D 4) ; NIL {if new pairs are added not at the front, and
the sub-update-form is not used}
#1=(A 1 B 2 C 3 D 4) ; #1# {if new pairs are added not at the front,
and the sub-update-form is used}
One final SETF puzzle:
(PROGN (SETF S (LIST (LIST 1)))
(SETF R (CAR S))
(SETF (CAAR S) (PROG1 2 (SETF (CAR S) (LIST NIL))))
(VALUES R S))
Is this valid?
(1) ; ((2)) {I think: Yes definitely.}
Is this?
(2) ; ((NIL)) {I think: Probably not.}
Try it in your implementation.
Hint: The big issue here is when the setf-method gets a handle on
the object whose cell is being stored into. The definition of DEFSETF
strongly implies that the first choice is the correct one.
-- Nick