From: Jack Vinson
Subject: messing with lists
Date: 
Message-ID: <43991@netnews.upenn.edu>
Hi Folks, again, (can you tell I'm doing a lot of hacking?)

I will try to describe my problem by example:

Start with
(setq my-list '((a b c d e f)))

Find out how many sets of data I will be playing with and end up with
my list looking like (for five sets of data)
((a b c d e f) (a b c d e f) (a b c d e f) (a b c d e f) (a b c d e f))

I wanted to set up a separate function to do this because there are a couple
different lists to which this applies.

I tried using this 
(defun fill-list (n form)
  (do ((i 1 (1+ i)))
      ((= i n) form)
      (setf form (append (list (car form)) form))))

(setf my-list (fill-list 5 my-list))

Which appears to work until I try setf on various elements in the sublists.  I
guess fill-list retains pointers, cuz when I (setf (nth 3 (car my-list)) 'x)
all of the d's get changed rather than just the one in the first sublist.


Does this make any sense.  I don't know at the start how many copies of the
list I will want, otherwise I would just make the initial setq of the correct
size.

Thanks for help on previous questions and this one and those to come....


Jack Vinson				······@linc.cis.upenn.edu
From: Barry Margolin
Subject: Re: messing with lists
Date: 
Message-ID: <1991Jun1.205020.24715@Think.COM>
In article <·····@netnews.upenn.edu> ······@linc.cis.upenn.edu (Jack Vinson) writes:
>I tried using this 
>(defun fill-list (n form)
>  (do ((i 1 (1+ i)))
>      ((= i n) form)
>      (setf form (append (list (car form)) form))))

A mostly equivalent definition would be

(defun fill-list (n form)
  (make-list n :initial-element (car form)))

A completely equivalent definition would be

(defun fill-list (n form)
  (append (make-list (1- n) :initial-element (car form))
	  form))

The difference between the two is whether the last cons in the resulting
list is the same as the original form or not.

Also, (push (car form) form) is a much clearer way to write what you were
writing with that long SETF form (it's also generally more efficient -- it
doesn't create garbage or search for the end of the list).

But, this has little to do with your specific problem....

>Which appears to work until I try setf on various elements in the sublists.  I
>guess fill-list retains pointers, cuz when I (setf (nth 3 (car my-list)) 'x)
>all of the d's get changed rather than just the one in the first sublist.

Lisp is all about manipulating first-class objects.  When manipulating
lists like this, you have to think in terms of the objects that are being
passed around.  Unless you specifically ask for a list to be copied, you
get the same list structure.  You can use (copy-list (car form)) or
(copy-tree (car form)) to make copies if that is what you want (whether you
need copy-list or copy-tree depends on the semantics of the objects that
are in the list).
-- 
Barry Margolin, Thinking Machines Corp.

······@think.com
{uunet,harvard}!think!barmar