I am reading the book Practical Common Lisp, and in the footnote5 of chapter22, page284, I saw a code snippet that made me confused.
I know that the variable list and tail have a list structure in common, but I am confusing that since tail will be assigned the value of 'new' each time during the iteration, why (setf (cdr tail) new) would affect the state of the variable list?
(do ((list nil) (tail nil) (i 0 (1+ i)))
((> i 10) list)
(let ((new (cons i nil)))
(if (null list)
(setf list new)
(setf (cdr tail) new))
(setf tail new)))
;;; => (0 1 2 3 4 5 6 7 8 9 10)
The invariant is that
tailis always the last cons cell oflist.On each iteration, a new cons cell is created holding the new value as
car. The first time through,listis set to this cons cell, andtailtoo. In all subsequent iterations, the new cons cell is appended by setting thecdrof the last cell to it, then settingtailto the new cell, to recreate the invariant.After first iteration:
After second:
Third: