Need to write a union function in lisp that takes two lists as arguments and returns a list that is the union of the two with no repeats. Order should be consistent with those of the input lists
For example: if inputs are ‘(a b c) and ‘(e c d) the result should be ‘(a b c e d)
Here is what I have so far
(defun stable-union (x y)
(cond
((null x) y)
((null y) x))
(do ((i y (cdr i))
(lst3 x (append lst3
(cond
((listp i)
((null (member (car i) lst3)) (cons (car i) nil) nil))
(t (null (member i lst3)) (cons i nil) nil)))))
((null (cdr i)) lst3)))
My error is that there is an “illegal function object” with the segment (null (member (car i) lst3))
Advice?
You’ve got your parens all jumbled-up:
Here’s your code as you probably intended it to be, with corrected parenthesization and some
ifs added where needed:There are still problems with this code. Your
dologic is wrong, it skips the first element inyif it contains just one element. And you callappendall the time whether it is needed or not. Note that calling(append lst3 nil)makes a copy of top-level cons cells inlst3, entirely superfluously.Such long statements as you have there are usually placed in
dobody, not inside the update form fordo‘s local variable.But you can use more specialized forms of
do, where appropriate. Here it is natural to usedolist. Following “wvxvw”‘s lead on using hash-tables for membership testing, we write:using a technique which I call “head-sentinel” (
zvariable pre-initialized to a singleton list) allows for a great simplification of the code for the top-down list building at a cost of allocating one extraconscell.