We continue this series of posts about functions that a beginning Lisp user coming from C++ might not have encountered with adjoin. There isn’t really too much to say about this one, other than to note that it is really a shortcut for a common construction.
The adjoin command is really just a conditional cons. It builds a new list by prepending a new element, but only if that element is not already present in the list under the equality condition defined by the :key and :test parameters.
CL-USER> (let ((a '(1 2 3 4 5))) (format t "Input list is: ~A~%" a) (format t "Adjoined with '1': ~A~%" (adjoin 1 a)) (format t "Adjoined with '10': ~A~%" (adjoin 10 a))) Input list is: (1 2 3 4 5) Adjoined with '1': (1 2 3 4 5) Adjoined with '10': (10 1 2 3 4 5)
Note that, as with cons, the place isn’t modified as it is with pushd. That is, (push 1 a) modifies ‘a’ so it points to the new list with the ‘1’ prepended. The adjoin and cons functions do not do this.
CL-USER> (let* ((a '(1 2 3 4 5)) (b (adjoin 1 a)) (c (adjoin 10 a))) (format t "~%A EQ B has value: ~A~%~%" (eq a b)) (plot-lists c a)) A EQ B has value: T C . A . . . . ----- ----- ----- ----- ----- ----- |A|D| --> |A|D| --> |A|D| --> |A|D| --> |A|D| --> |A|D| -->NIL ----- ----- ----- ----- ----- ----- | | | | | | | | | | | | | | | | | 5 | | | | 4 | | | 3 | | 2 | 1 10