DELETE
works by changing the CDR
of the previous cons cell of the list to point to the one past the element(s) being deleted. But if you're deleting the first element of the list, there is no previous cons cell to modify.
Although this implementation isn't actually specified by the language standard, it's the way practically every implementation works.
Since there's no previous cons cell to modify when deleting the first element of the list, it simply returns the second cons cell. So even though DELETE
is permitted to modify the list, you still must assign the result to your variable to handle this case. Also, it should be emphasized that destructive behavior is only allowed by the standard, not required. So there's a remote possibility that some implementation might not implement it destructively at all, and you must allow for that as well.
And even if DELETE
worked by modifying CARs instead of CDRs, there's still a case that it can't do destructively: deleting all the elements of a list, e.g.
(setq *test* (list 'a 'a))
(delete 'a *test*)
This results in an empty list, i.e. NIL
. But *test*
still contains the cons cell that was the head of the original list, and there's no way for DELETE
to change that. So you must do:
(setq *test* (delete 'a *test*))
to set *test*
to NIL
.