[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

setf order of evaluation



   Date: Wed, 9 Sep 87 14:40 EDT
   From: David A. Moon <franz!STONY-BROOK.SCRC.Symbolics.COM!Moon>

       Date: 9 September 1987, 10:31:51 EDT
       From: Timothy Daly <DALY@ibm.com>

       Given

	(setq r '(a 1 b 2 c 3))
	(setq s r)
	(setf (getf r 'b) (progn (setq r nil) 6))

       what is the value of R and S?

       Note that P97 of CLtL states that SETF guarantees the
       left-to-right order of evaluation of its arguments.

       (yes, i know it is crufty to change R).

       Both Symbolics and Lucid seem to generate
	R = (B 8) and S = (A 1 B 2 C 3)

       which implies that the second argument of setf
       is evaluated first. What did I miss?

   It's not a good idea to speak of "arguments" when dealing with
   forms that aren't function calls.  It's less confusing to speak
   of subforms.  The subforms of that setf that get evaluated are

     r
     'b
     (progn (setq r nil) 6)

   so I think the behavior you describe is a bug (although the description
   in CLtL is so ambiguous that the implementors of the respective systems
   could easily disagree with me.)

   I didn't look inside the Lucid implementation, but in the Symbolics 
   implementation the source of the bug is that (get-setf-method 'r)
   returns NIL, NIL, (#:G6411), (SETQ R #:G6411), R, whereas it should
   return (#:G6410), (R), (#:G6411), (SETQ R #:G6411), #:G6410.  See
   CLtL page 104 for the description of the meaning of these values.

   Changing it to return the latter makes your SETF example behave as you
   expected, evaluating R -before- bashing it, and setq'ing it to the updated
   property list -after- setq'ing it to nil.

Franz Inc.'s Common Lisp ("Allegro CL") ends up with r = nil and
s = (a 1 b 6 c 3).  However, it returns the same 5 forms for
(get-setf-method 'r) that Symbolics does, and in fact these 5 forms
are given as an example on p. 105 of CLtL.