Если идиома «минусы впереди, финиширование задним ходом» не подходит вам (если вам, например, нужно передать список другим функциям во время его создания), есть также «отслеживать» конец "трюк. Тем не менее, возможно, будет проще построить список, поместив его в начало, а затем завершить, используя reverse или nreverse, прежде чем, наконец, использовать его.
По сути, это позволяет вам составлять список в правильном порядке при его создании за счет необходимости отслеживать его.
(defun track-tail (count)
(let* ((list (cons 0 nil))
(tail list))
(loop for n from 1 below count
do (progn
(setf (cdr tail) (cons n nil))
(setf tail (cdr tail))
(format t "With n == ~d, the list is ~a~%" n list)))
list))
Это дает следующий вывод:
CL-USER> (track-tail 5)
With n == 1, the list is (0 1)
With n == 2, the list is (0 1 2)
With n == 3, the list is (0 1 2 3)
With n == 4, the list is (0 1 2 3 4)
(0 1 2 3 4)