[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: setq with memory
- To: clisp-list <clisp-list@ma2s2.mathematik.uni-karlsruhe.de>
- Subject: Re: setq with memory
- From: Steve Haflich <smh@Franz.COM>
- Date: Thu, 27 Jun 1996 10:04:34 -0700
- In-reply-to: Your message of "Thu, 27 Jun 1996 06:00:06 +0200." <199606261724.KAA28516@binkley.jpl.nasa.gov>
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.