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

RE:EQ



    Date: 26 May 88 11:01 EST
    From:     STERRITT%SDEVAX.decnet@ge-crd.arpa

	    I have some code that does surgery (setf's of nth's) on lists in
    a Defstruct.  Since some of the fields are identical, the lists are eq.
    This means (obviously, once you know about it) that if you change slot A,
    slot B is smashed too!
	    E.G.:
    (defstruct foo
	    (a '(0.0 0.0))
	    (b '(0.0 0.0)))
    ;;compile, then:
    (setf bar (make-foo))
    (setf (nth 0 (foo-a bar)) 4.5)
    (foo-a bar)
    -> (4.5 0.0)
    (foo-b bar)
    -> (4.5 0.0)

;;; Right, so the lesson is to make sure you create the *bashable*
;;; list-structure each time it's instantiated.  E.g.

(defstruct foo
  (a (list 0.0 0.0))
  (b (list 0.0 0.0)))

;;; A similar, annoying, subtle bug can occur while bashing 
;;; lists in compiled functions.  Consider:

(defun yu-shiang-kitty (X)
  (let ((SOME-LIST '(1))
	(TEMP-TOTAL))
    (setq TEMP-TOTAL (+ X (first SOME-LIST)))
    (rplaca SOME-LIST X)
    TEMP-TOTAL)
  )

(YU-SHIANG-KITTY 5)
	
-> 6

;;; As expected.  Care to guess the result of
;;; rerunning (YU-SHIANG-KITTY 5)?

;;; NICHAEL

----------------------------------------------------
"You know me", he said, "All I need are loose shoes,
a tight schedule and a warm place to write Lisp."