Потому что cdr
последнего элемента - nil
, и вы устанавливаете переменную на это.
Как правило, car
каждого cons
является значением (которое может быть указателем на другой список), а cdr
является указателем на оставшуюся часть списка. Поэтому, когда вы просматриваете список, вы обычно хотите работать на car
.
(progn
(setq lst '(3 5 7))
(while (cdr lst))
(setq lst (cdr lst)))
(print (car lst)))
Любой основной Lisp введение будет иметь лучшие зрительные образы, чем у меня, но если вы читали один, это должно выглядеть знакомым. Основным строительным блоком списка является ячейка cons с car
и cdr
(имена, по-видимому, сохраняют имена регистров, используемые в первых реализациях Lisp).
+------+------+
| car | cdr |
+------+------+
Ваш список с тремя элементами будет иметь три conses; (3 . (5 . (7 . nil)))
или графический
+---+---+ +---+---+ +---+---+
| . | o--->| . | o--->| . | o---#
+-v-+---+ +-v-+---+ +-v-+---+
3 5 7
Так car
первых минусов есть (указатель) значение 3, а его cdr
есть (указатель) на следующий cons
в списке.
'(равный lst (cdr lst))' действует только для пустого списка. Мои плохие навыки LISP говорят мне, что это, вероятно, должно быть «(равно lst (car lst))». –
Моя ошибка. с «автомобилем» тот же результат. – jone
@HristoIliev: '(equal lst (car lst))' is * also * only true для пустого списка (и некоторых странных круговых списков, но пока не будем игнорировать их ...). – npostavs