DELETE
работа путем изменения CDR
в предыдущих минусах ячейки списка, чтобы указать на один мимо элемент (s) удаляется. Но если вы удаляете первый элемент списка, для изменения нет предыдущей ячейки cons.
Хотя эта реализация на самом деле не указана стандартом языка, это практически практически каждая реализация.
Поскольку для удаления первого элемента списка не существует предыдущей ячейки cons, она просто возвращает вторую ячейку cons cons. Поэтому даже если DELETE
разрешено изменять список, вы все равно должны назначить результат своей переменной для обработки этого случая. Кроме того, следует подчеркнуть, что деструктивным поведением является только разрешено по стандарту, а не требуется. Таким образом, есть отдаленная возможность того, что некоторая реализация может вообще не реализовать ее разрушительно, и вы также должны это учитывать.
И даже если DELETE
работал с изменением CAR, а не с CDR, все еще существует случай, когда он не может разрушить: удаление всех элементов списка, например.
(setq *test* (list 'a 'a))
(delete 'a *test*)
Это приводит к пустой список, т.е. NIL
. Но *test*
все еще содержит ячейку cons, которая была главой исходного списка, и нет никакого способа для DELETE
, чтобы изменить это. Так что вы должны сделать:
(setq *test* (delete 'a *test*))
установить *test*
в NIL
.
Ну, не столько «предыдущее значение переменной» как «структура значения, которое имеет по крайней мере эта переменная». В конце концов, структура распределения не является чем-то необычным. – Vatine
И это не ограничивается «значением переменной [a]». Вы можете сделать, например, '(delete 1 (rest some-list))'. Ему просто нужен список в качестве аргумента; это не макрос и не нуждается в _place_. –
@mck Обратите внимание, что результаты в первом случае не так непредсказуемы, как «вы были съедены грубой». В то время как автомобиль и cdr любой ячейки cons в списке могут быть изменены, они все равно будут cons-ячейками. В первом случае 'a' всегда будет ячейкой cons после вызова' (delete 2 a) ', даже если после этого автомобиль и cdr будут разными. Еще важнее то, что это все равно будет той же самой, что и раньше. Например, см. [Этот образец кода] (http://pastebin.com/qVUfHeV8). –