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

Issue: SETF-METHOD-FOR-SYMBOLS (version 1)



    Date: Mon, 21 Sep 1987  22:57 EDT
    From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>

    I tried Daly's example in Spice Lisp, and it gave what Moon proposes as
    the intuitive answer: both R and S end up with (A 1 B 6 C 3).  And in
    the same Lisp, (get-setf-method 'foo) returns the values prescribed in
    CLtL: nil nil (#:G1) (setq foo #:G1) foo.  So the statement in Moon's
    proposal that Daly's example is impossible to implement with with this
    set of values is false.  There might be other examples which dictate the
    change in get-setf-method that Moon proposes, but this particular
    case does not force the issue.

    The trick here is that the get-setf-method value-set for Getf sets up
    all of the necessary bindings, rather than doing this in the method for
    a symbol:

    (get-setf-method '(getf a b)) =>

    (#:G1 #:G2)
    (A B)
    (#:G3)
    (progn (setq #:G1 (%putf #:G1 #:G2 #:G3))
	   (setq A #:G1)
	   #:G3)
    (getf #:G1 #:G2)

    Is there some problem here I don't see?

Doesn't this only show that getf's setf-method is calling a private
copy of get-setf-method for the first argument, rather than recursively
calling the regular get-setf-method?  If not, how did it know that a
temporary variable needed to be bound to a?  Perhaps it just always
binds a temporary variable to any first argument; but then the difference
between the CLtL setf-method for variables and my proposed new one
is ignored by Spice Lisp in this case.

It's true that I shouldn't have said it was impossible to implement setf
correctly in the face of the setf-method prescribed by CLtL.  I should
have realized that an implementation was free to introduce more
temporary variables than the ones implied by the setf-method.  However,
consider this example, using the setf-method for ldb prescribed by CLtL
page 106:

(setq a 0)
(incf (ldb (byte 2 2) a) (setq a 2))

Does this leave a=8, a=10, or a=2?  I believe 8 is what is intended by
page 99's statement about order of evaluation of subforms.

Note that no arguments about an implementation having its own setf method
for ldb are relevant here.  If users are to be able to write hairy setf
methods in portable code, which I assume is a goal otherwise why did we
document all this stuff, then setf-methods written in the style of the
one CLtL gives for LDB have to work portably and produce equivalent effects
in all implementations.

    For what it's worth, I get the following:

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

    (setf (nthcdr 2 r) (progn (setq r nil) 6))
    r= nil, s = (a 1 . 6)

    I think that these values are right, since changing the tail of the old
    value of R can't set anything back into R to override the explict SETQ.

I agree.

    Anyone disagree?  Our code gets no failures trying to setq the nthcdr of
    nil, or whatever.

    Unless I'm missing something, I would say that these examples shoot down
    Moon's proposal in its current form.

Do you still think that after seeing my reaction above?  If so, I think we
need to back off and consider precisely what CLtL p.99 was supposed to be
saying.