Search code examples
lispunion

Common LISP: Make Your Own Union Function


I'm trying to make my own union function and realizing how much I dislike LISP. The goal is to give the function two lists and it will return a set theoretic union of the two. My attempted solution has grown increasingly complex with the same result: NIL. I can't change that from being the result no matter what I do.

I was thinking of building a separate list in my "removeDuplicates" function below, but then idk how I'd return that with recursion. I think what's happening is my "removeDuplicates" function eventually returns an empty list (as intended) but then an empty list is return at every level of the stack when the recursion unfurls (starts returning values up the stack) but I could be wrong. I've always had trouble understanding recursion in detail. The code is below.

(defun rember (A LAT)
  (cond
   ((null LAT) ())
   ((EQ (car LAT) A) (cdr LAT))
   (T (cons (car LAT)(rember A (cdr LAT))))
   )
  )

(defun my_member (A LAT)
  (cond
   ((null LAT) nil)
   ((EQ (car LAT) A) T)
   (T (my_member A (cdr LAT)))
   )
  )

(defun removeDuplicates (L)
  (cond
   ((null L) '())
   ((my_member (car L) (cdr L)) (rember (car L) L) (removeDuplicates (cdr L)))
   (T (removeDuplicates (cdr L)))
   )
  )

(defun my_union (A B)
  (setq together(append A B))
  (removeDuplicates together)
  )

I'm aware most people are not a fan of this format of LISP code, but I prefer it. It allows me to see how parentheses line up better than if you just put all the closing parentheses together at the end of functions and condition blocks.

If I run (my_union '(a b) '(b c)) for example, the result is NIL.


Solution

  • When you call removeDuplicates recursively in the last condition, you're not combining the result with the car of the list, so you're discarding that element.

    You're also not using the result of rember.

    (defun removeDuplicates (L)
      (cond
       ((null L) '())
       ((my_member (car L) (cdr L)) 
        (cons (car L) 
              (removeDuplicates 
               (rember (car L) (cdr L)) 
               ))
        )
       (T (cons (car L) (removeDuplicates (cdr L))))
       )
      )