vinson@linc.cis.upenn.edu (Jack Vinson) (06/01/91)
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 vinson@linc.cis.upenn.edu
barmar@think.com (Barry Margolin) (06/02/91)
In article <43991@netnews.upenn.edu> vinson@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. barmar@think.com {uunet,harvard}!think!barmar