From: Bruce Feist
Subject: Novice C Question
Date: 
Message-ID: <731813527.AA01482@blkcat.UUCP>
|>I'm trying to write a series of Common LISP functions to implement a
dk> stopwatch. 

|>(defun stopwatch () '(NIL . 0))

|>This isn't working properly.  (stopwatch) appears to always return the same
|>stopwatch; if a watch's state has been altered by a call to
(stopwatch-start),
|>all future stopwatches created reflect the same changes.

dk> When you quote a cons as in '(NIL . 0) you are creating a constant, 

dk> So simply redefine stopwatch to
dk> (defun stopwatch () (cons nil 0))

dk> This will return a fresh cons each time stopwatch is called.
dk>  Now you can  setf car's to your heart's content.  :-)

Thanks.  Between your reply and others I have recieved through E-Mail and (I
suspect) here, I see the problem and solution.  So, now onward to another issue
which I suspect may be religious:  Should I setf cars and cdrs as I  did in the
example I posted, or should I rplaca and rplacd?  Why?

Bruce

From: Carl L. Gay
Subject: Re: Novice C Question
Date: 
Message-ID: <CGAY.93Mar11005851@majestix.cs.uoregon.edu>
   From: ···········@f615.n109.z1.fidonet.org (Bruce Feist)
   Date: 10 Mar 93 4:24pm PST

						   So, now onward to another issue
   which I suspect may be religious:  Should I setf cars and cdrs as I  did in the
   example I posted, or should I rplaca and rplacd?  Why?

It makes no difference; they are the same.  (setf (car x) 1) is
converted into (something like) (rplaca x 1) by the compiler.  I
personally prefer using SETF in this case since I don't have to
remember argument order.

I think the issue you're really trying to get at is whether to use
destructive operations or whether to allocate new storage.  There are
tradeoffs:  Destructive operations are more dangerous.  i.e., you are
more likely to introduce bugs with that style of programming, and they
will be harder to find (as you observed).  Allocating new storage
allocates more storage :-) but that's why there's a garbage collector.

My advice is to (in general) use the "allocate new storage" approach
at least while developing an application and then later, IF NECESSARY,
try to reduce memory use.

These issues are covered in the FAQ, which you can get from
ftp.think.com:/think/lisp/faq-1.30.  Search for "rplaca".
From: Lou Steinberg
Subject: Re: Novice C Question
Date: 
Message-ID: <LOU.93Mar14170130@atanasoff.rutgers.edu>
In article <·················@blkcat.UUCP> ···········@f615.n109.z1.fidonet.org (Bruce Feist) writes:

   Should I setf cars and cdrs as I  did in the
   example I posted, or should I rplaca and rplacd?  Why?

Neither - in the example you posted you were really using cons cells
to implement a 2-field record.  But what if someday you need to add
another field (e.g. a resolution (.1 vs .01 seconds) or a count of
starts/stops)?  You'll have to find all rplaca/rplacd's or setf's of
car/cdr's and decide for each one if it is accessing this data
structure, to know if it needs changing.

It is much better style to use a defstruct for the representation.  If
you insist on cons cells, at least define functions or macros
watch-started and watch-time and correpsonding setf forms and call
those instead of rplaca/a or setf of car/cdr.
--
					Lou Steinberg

uucp:   {pretty much any major site}!rutgers!aramis.rutgers.edu!lou 
internet:   ···@cs.rutgers.edu