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

Side effects and SETF

    From: Carl W. Hoffman <CWH at MIT-MC>
	From: Guy.Steele at CMU-10A
	I must agree with GJC that the tradition of left-to-right evaluation
	be maintained in MacLISP/LISP Machine LISP for consistency.  The SETF
	machinery ought to be gone over with a fine-toothed comb, as well as
	the destructuring machinery and anything else vaguely related, to make
	sure things are being kept consistent.
    SETF is a special form, not a subr.  I consider the fact that GJC's
    example worked interpreted to be a bug.  His example only makes sense if we
    view SETF as a subr and CAR as returning a locative.  But Lisp doesn't work
    that way.
Hmm... you seem to be suffering from "Aunt Agatha syndrome": "Why, I can't
imagine it working any other way... so it must be this way!"
To me, his example makes sense under a model other than the locative model:
SETF is a special form that effectively turns any function call as its
first argument into a special form--but arguments of that call are NOT special
forms.  Thus, (SETF (CAR (get y x)) (hack z)) treats the upper-case part
as special forms, so to speak.  Now note too that the "special function call"
ti to CAR, a function with no side effects, and in general the selector
operation fed to a SETF is supposed to have no side effects.  The computations
of the argument to thast selector may have side effects, however, and so
such computations should be done left-to-right.  Thus in
(SETF (GET x y) z), GET is a selector (side-effect-less), and the forms
x, y, and z should be executed once each and in that order.  By the same
token, (PUSH x (GET y z)) treats the GET as special, but x, y, and z
are ordinary forms and should be executed once each and in that order.

In these examples CAR and GET are not being treated as returning
locatives (though that is also a helpful metaphor); instead, they
may be considered "keywords" for PUSH and SETF--part of the template
for the total special form.  Any ordinary forms within that template
should be executed left-to-right.