0

I am trying to do a function that removes duplicates from a list using Common Lisp on LispWorks.

So I did two functions. The first one "remove-e" removes an element from a list and a second one "remove-rep" uses the first one to return a list without duplicates.

Here is my code for the first one:

(defun remove-e (L e) (if (null L) L (if (= e (car L)) (remove-e (cdr L) e) (cons (car L) (remove-e (cdr L) e))))) 

It works good when given a list of numbers but when I give it letters, I get this error:

(remove-e '(a a b a d a g a h t) a) Error: The variable A is unbound. 

For my second function:

(defun remove-rep (l)    (if (null l) l (cons (car l) (remove-rep (remove-e (cdr l) (car l)))))) 

This is the error message that I get when trying to test it:

CL-USER 12 : 6 > (remove-rep '(1 2 3 1 5 1 1)) Error: The variable   is unbound. 

I saw that there are some similar questions, but couldn't find the common points of my program with these: Unbound variable in Lisp , Unbound variable in Common Lisp

7
  • The = function is for comparing numbers. Use eql if you want to be able to compare numbers or symbols, use equal if you want to be able to compare things like strings and lists. Commented Apr 29, 2017 at 10:04
  • You have some Arabic characters after defun remove-rep (l). They're Unicode code point 0x8a0. Commented Apr 29, 2017 at 10:08
  • fileformat.info/info/unicode/char/8a0/index.htm Commented Apr 29, 2017 at 10:08
  • @Barmar even with eql and equal I'm getting the same error. How to remove the Arabic characters? Commented Apr 29, 2017 at 10:18
  • You'll also need to quote the a symbol to prevent it being evaluated as a variable. Commented Apr 29, 2017 at 10:20

1 Answer 1

3

remove-e only works with a list of numbers, because you're using = to compare elements. If you want to be able to work with symbols as well, use eql:

(defun remove-e (L e) (if (null L) L (if (eql e (car L)) (remove-e (cdr L) e) (cons (car L) (remove-e (cdr L) e))))) 

Then when you call it, you have to quote the symbol argument, to prevent it from being evaluated as a variable.

(remove-e '(a a b a d a g a h t) 'a) 

The problem in remove-rep is that you somehow typed some non-printing, multi-byte characters at the end of the first line. It works correctly with those characters removed. Try retyping the function, or just copy/paste this:

(defun remove-rep (l) (if (null l) l (cons (car l) (remove-rep (remove-e (cdr l) (car l)))))) 

BTW, Lisp programmers don't generally put ) on new lines like you do, they put them at the end of the line like this.

Sign up to request clarification or add additional context in comments.

6 Comments

Thank you for the clarifications! It works fine now. I was just wondering where those characters come from? Obviously I was not programming in Arabic.
I have no idea, you must have inadvertently types characters with the Alt key.
I have one more question please. What paradigm seems best suited for this problem? Is it when using Lisp or Prolog?
I haven't done much Prolog programming, but I think it's best suited to problems that involve pattern matching or filling in blanks. Procedural languages like Lisp can only solve a problem in one direction: you give it parameters X and Y and it calculates a result Z. In Prolog, you can give X and Z, and it will try to find Y.
Based on that, can we say that Prolog is more suited since it gives us more options and we are not stuck in only one direction?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.