From: Scott Sheffield
Subject: Clearing data
Date: 
Message-ID: <37B1BD21.DC60FDF5@lmco.com>
I am running some interleaf  lisp code. It seems that some of my global
variables are retaining some of the information from the last time I ran
the program.
I can shut down and start a new session and I won't have a problem, but
it is a problem if I run the program twice in the same session. I use
defvar to
declare my variables and set them to zero  in the header. What am I
doing wrong?

Thanks
Scott
From: Kent M Pitman
Subject: Re: Clearing data
Date: 
Message-ID: <sfwiu6mf4u5.fsf@world.std.com>
Scott Sheffield <·················@lmco.com> writes:

> I am running some interleaf  lisp code. It seems that some of my global
> variables are retaining some of the information from the last time I ran
> the program.
> I can shut down and start a new session and I won't have a problem, but
> it is a problem if I run the program twice in the same session. I use
> defvar to
> declare my variables and set them to zero  in the header. What am I
> doing wrong?

I don't know interleaf, but if it's ANSI compliant then 
 (a) DEFVAR does an assignment only once when the code is executed
     (presumably by LOAD).  If you are not calling LOAD a second time,
     there is not even the chance that it will get re-evaluated.

     I'm not sure what a "header" is; maybe some interleaf thing.
     (It's possible it is the moral equivalent of load with per-file
      code to execute? Ask someone
     interleaf-savvy, I guess. Or consult your doc.)

 (b) DEFVAR does the assignment only if unbound, so even if LOAD were
     called a second time, (DEFVAR *FOO* (RANDOM 100)) would not change
     the value of *FOO* if (BOUNDP '*FOO*) returns true.
   
You have several options, but they might include:

 See if interleaf has a DEFPARAMETER or similar facility.
 In CL, that will unconditionally assign the variable instead
 of assigning it only if unbound.  Some variables may not want
 to be reset, so don't just learn to use DEFPARAMETER
 always--think for each variable what the appropriate behavior is.

 You may need to be calling LOAD to reload files.  But if that's
 so, consider remodularizing your code to not require this.  e.g.,
 replace:

   (defvar *foo* ...foo computation...)
   (defvar *bar* ...bar computation...)

 with

   (defvar *foo*)
   (defvar *bar*)

   (defun set-things-up ()
     (setq *foo* ...foo computation...)
     (setq *bar* ...bar computation...))

   (set-things-up)

 and then just use (set-things-up) again later if you need to
 reset your system.  Or you may want to do:

   (defvar *foo*)
   (defvar *bar*)

   (defvar *all-set-up* nil)

   (defun set-things-up (&key (force nil))
     (when (or (not *all-set-up*) force)
       (setq *foo* ...foo computation...)
       (setq *bar* ...bar computation...)
       (setq *all-set-up* t)))


 Of course, it sounds like for your need you want force to default to 
 t instead of nil, and you may not need it at all.  But I mention
 the paradigm just for generality.