From: Oliver K. <ng...@gm...> - 2014-07-23 13:05:22
|
Hello Lispers, day 3 of my selflearning Lisp course I've started some coding and BANG - I'm lost. Changing an element of a sublist as expected: * (let ((l1 (list (list 1 1) (list 1 1)))) (setf (car (nth 1 l1)) 2) l1) => ((1 1) (2 1)) Changing an element of a sublist created with make-list is unexpected to me: * (let ((l1 (make-list 2 :initial-element (list 1 1)))) (setf (car (nth 1 l1)) 2) l1) => ((2 1) (2 1)) Neither in any tutorial nor in Hyperspec nor in newsgroups I could find an explanation for this different behavior. As told in HyperSpec make-list[1] "Returns a list of length given by size, *each* of the elements of which is initial-element." it seems that the initial-element is referenced by all list entries. But that's not true as seen by changing a level 1 element: * (let ((l1 (make-list 2 :initial-element (list 1 1)))) (setf (nth 1 l1) '(1 2)) l1) => ((1 1) (1 2)) Next I thought setf is not capable of using nested structure addressing. But that's not true either as seen in the first example. I've read that make-list uses Cdr-Coding[2], but that only seems to be for storage efficiency and should not change any functional behavior. BTW: Everything seems to be Common-Lisp conform as clisp shows the same results. It's just me not knowing why. Could please anybody enlight me about what's causing the different resluts. Thanks and Regards, Oliver [1] http://www.lispworks.com/documentation/HyperSpec/Body/f_mk_lis.htm [2] http://common-lisp.net/project/bknr/static/lmman/fd-con.xml#cdr-code |