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

Re: setq with memory



   From: gat@aig.jpl.nasa.gov (Erann Gat)
   
   A more general version of this macro, and one that illustrates
   slightly better programming style (but only slightly) goes:
   
   (defmacro record-eval (expression)
     `(progn (push ',expression *mem*)
             ,expression))
   
   This is a more general way of accomplishing the same thing because
   it allows you to record any expression for later playback, not just
   setq.  It also does the recording at eval time rather than macro
   expansion time, which is probably closer to what Dr. Olmi had in
   mind.
   
But it is important that a "form" cannot be played back in this way,
absent its environment.  Consider:

(defun kons (a b) `(cons ,a ,b))

(defun test (x y)
  (macrolet ((kons (a b) `(list ,a ,b)))
    (record-eval (kons x y))))

The form recorded on *mem* won't do the same thing when passed to
eval, since eval always executes relative to the null lexical
environment.  A CL form is meaningless without its environment.

A way more in keeping with CL semantics would be capture a "form" would
be something like:

(defmacro record-eval (expression)
  `(let ((continuation #'(lambda () ,expression)))
     (push continuation *mem*)
     (funcall continuation)))

In this case the elements of *mem* are opaque function objects that
properly capture the lexical environment in which they were defined.
Each could be reexecuted using funcall.  The orignal expression could
only portably be retrieved using the ANS CL
function-lambda-expression, on those implementations that support it
and don't just always return NIL.