From: Roberto Olmi
Subject: help: implementing setq with memory
Date: 
Message-ID: <olmi.22.00097E0E@iroe.iroe.fi.cnr.it>
I am a lisp beginner, so my question could have a straightforward answer.

I am trying to implement a simple function MY-SETQ which does exactly what 
SETQ does, and records in a list *MEM* the actions done. The objective is to 
have the possibility of seeing (and executing, by MAPCAR and EVAL) the 
assignements done.

I have implemented MY-SETQ as follows:

(defun my-setq (x y)
     (set x (eval y))
     (setq *MEM* (cons (list 'setq x y) *MEM*)))

After an inizialization of *MEM* to nil, the commands look like these:

(my-setq 'x ''abc)
(my-setq 'y ''(sin 1.2345))

and *MEM* is, in the above case: ((setq y '(sin 1.2345)) (setq x 'abc))

so that, for example, (mapcar 'eval *MEM*) does the required re-assignement.

The question is: how can I implement MY-SETQ such that the arguments are 
written in a more "natural" way, to say:  (my-setq  x  'abc) ?


Thank you to all,

Roberto Olmi
IROE-CNR
Firenze (Italy)
From: Barry Margolin
Subject: Re: help: implementing setq with memory
Date: 
Message-ID: <4r1nis$aha@tools.bbnplanet.com>
In article <··········@news.cis.okstate.edu>,
Mark McConnell  <·······@math.okstate.edu> wrote:
>(defmacro my-setq (x y)
>  `(let ((y-value ,y)) ; this causes y to be evaluated
>     (push (list 'setq ',x y-value) *MEM*)
>     (setq ,x y-value)))

You shouldn't use y-value in the *MEM* list.  Otherwise, you'll get double
evaluation when you later do (mapcar #'eval *MEM) -- one evaluation done
when my-setq was used, and a second one when this eval runs.  So that line
of the macro should be

(push (list 'setq ',x ',y) *MEM*))

or, as I wrote in my version of the macro:

(push `(setq ,',x ,',y) *MEM*)

>The call (my-setq c (+ 2 2)) expands into the following code:
>
>(let ((y-value (+ 2 2))) ; so y-value is bound to 4
>  (push (list 'setq 'c y-value) *MEM*)
>  (setq c y-value))

Your error doesn't affect this example, because the result of mathematical
operations is a number, which self-evaluates.  But try your example with
this:

(my-setq c (car '((+ 1 2))))

After doing this, *MEM*'s first element will be:

(setq c (+ 1 2))

And when you re-evaluate it, it will set c to 3 instead of (+ 1 2) like it
did during the initial evaluation.

Another solution is to quote the second argument to setq, e.g.

(push `(setq ,',x ',y-value) *MEM*)
-- 
Barry Margolin
BBN Planet, Cambridge, MA
······@bbnplanet.com -  Phone (617) 873-3126 - Fax (617) 873-6351
(BBN customers, please call (800) 632-7638 option 1 for support)