What's the difference between `eq`

, `eql`

, `equal`

and `equalp`

, in Common Lisp? I understand that some of them check types, some of them check across types an all that, but which is which? When is one better to use than the others?

0 votes

`eq`

, `eql`

, `equal`

and `equalp`

, in Common Lisp? I understand that some of them check types, some of them check across types an all that, but which is which? When is one better to use than the others?

0 votes

Some more notes:

Most CL functions implicitly use EQL when no test is specified

See also STRING-EQUAL, = and TREE-EQUAL

At the core of EQ is usually a pointer comparison

And a rough guide:

To compare against... Use... Objects/Structs EQ NIL EQ (but the function NULL is more concise and probably cheaper) T EQ (or just the value but then you don't care for the type) Precise numbers EQL Floats = Characters EQL or CHAR-EQUAL Lists, Conses, Sequences EQ (if you want the exact same object) EQUAL (if you just care about elements) Strings EQUAL (case-sensitive), EQUALP (case-insensitive) STRING-EQUAL (if you throw symbols into the mix) Trees (lists of lists) TREE-EQUAL (with appropriate :TEST argument)

Note that for efficiency usually EQ >> EQL >> EQUAL >> EQUALP.

0 votes

From Common Lisp: Equality Predicates

`(eq x y)`

is true if and only if`x`

and`y`

are the same identical object.The

`eql`

predicate is true if its arguments are`eq`

, or if they are numbers of the same type with the same value, or if they are character objects that represent the same character.The

`equal`

predicate is true if its arguments are structurally similar (isomorphic) objects. A rough rule of thumb is that two objects are equal if and only if their printed representations are the same.Two objects are

`equalp`

if they are equal; if they are characters and satisfy char-equal, which ignores alphabetic case and certain other attributes of characters; if they are numbers and have the same numerical value, even if they are of different types; or if they have components that are all`equalp`

.

Here are some examples from the same page I linked to above:

```
(eq 'a 'b) is false.
(eq 'a 'a) is true.
(eq 3 3) might be true or false, depending on the implementation.
(eq 3 3.0) is false.
(eq 3.0 3.0) might be true or false, depending on the implementation.
(eq #c(3 -4) #c(3 -4))
might be true or false, depending on the implementation.
(eq #c(3 -4.0) #c(3 -4)) is false.
(eq (cons 'a 'b) (cons 'a 'c)) is false.
(eq (cons 'a 'b) (cons 'a 'b)) is false.
(eq '(a . b) '(a . b)) might be true or false.
(progn (setq x (cons 'a 'b)) (eq x x)) is true.
(progn (setq x '(a . b)) (eq x x)) is true.
(eq #\A #\A) might be true or false, depending on the implementation.
(eq "Foo" "Foo") might be true or false.
(eq "Foo" (copy-seq "Foo")) is false.
(eq "FOO" "foo") is false.
(eql 'a 'b) is false.
(eql 'a 'a) is true.
(eql 3 3) is true.
(eql 3 3.0) is false.
(eql 3.0 3.0) is true.
(eql #c(3 -4) #c(3 -4)) is true.
(eql #c(3 -4.0) #c(3 -4)) is false.
(eql (cons 'a 'b) (cons 'a 'c)) is false.
(eql (cons 'a 'b) (cons 'a 'b)) is false.
(eql '(a . b) '(a . b)) might be true or false.
(progn (setq x (cons 'a 'b)) (eql x x)) is true.
(progn (setq x '(a . b)) (eql x x)) is true.
(eql #\A #\A) is true.
(eql "Foo" "Foo") might be true or false.
(eql "Foo" (copy-seq "Foo")) is false.
(eql "FOO" "foo") is false.
(equal 'a 'b) is false.
(equal 'a 'a) is true.
(equal 3 3) is true.
(equal 3 3.0) is false.
(equal 3.0 3.0) is true.
(equal #c(3 -4) #c(3 -4)) is true.
(equal #c(3 -4.0) #c(3 -4)) is false.
(equal (cons 'a 'b) (cons 'a 'c)) is false.
(equal (cons 'a 'b) (cons 'a 'b)) is true.
(equal '(a . b) '(a . b)) is true.
(progn (setq x (cons 'a 'b)) (equal x x)) is true.
(progn (setq x '(a . b)) (equal x x)) is true.
(equal #\A #\A) is true.
(equal "Foo" "Foo") is true.
(equal "Foo" (copy-seq "Foo")) is true.
(equal "FOO" "foo") is false.
(equalp 'a 'b) is false.
(equalp 'a 'a) is true.
(equalp 3 3) is true.
(equalp 3 3.0) is true.
(equalp 3.0 3.0) is true.
(equalp #c(3 -4) #c(3 -4)) is true.
(equalp #c(3 -4.0) #c(3 -4)) is true.
(equalp (cons 'a 'b) (cons 'a 'c)) is false.
(equalp (cons 'a 'b) (cons 'a 'b)) is true.
(equalp '(a . b) '(a . b)) is true.
(progn (setq x (cons 'a 'b)) (equalp x x)) is true.
(progn (setq x '(a . b)) (equalp x x)) is true.
(equalp #\A #\A) is true.
(equalp "Foo" "Foo") is true.
(equalp "Foo" (copy-seq "Foo")) is true.
(equalp "FOO" "foo") is true.
```

0 votes

From here and my teacher's slides

eqtests to see if its arguments(represented by the same chunk of computer memory) are same symbol or not.

For Example:

(eq ‘A ‘B) NIL

(eq ‘RAM ‘RAM) T

(eq (cons 'a 'b) (cons a' b')) ; *This is because different calls are made for both cons so they will obviously be allocated different memory chunks*

eqlfirst tests to see if its arguments satisfy EQ, if not, it tries to see if they are numbers of the same type and values.

For Example:

(eql 4 4.0) NIL

(eql 4 4) T

Now note a **difference**:

(eq 4.0 4.0) NIL ;Depend upon platform as described in first (accepted)answer

(eql 4.0 4.0) T ;type and value of arguments is same

*On some implementations (eq 4.0 4.0) may return true because it is not specified in the standard whether an implementation should keep just one copy of numbers and chars in memory, like it does with symbols).As a rule of thumb* **don’t use eq on numbers and characters**, *unless you really know what you’re doing.*

equalis a “saner” comparison function. As a rule of thumb, you can think of it as telling you whether two objects look the same (structurally similar, or isomorphic). It is probably the operator you want to use for general equality. It behaves like eql for numbers, characters and symbols, but for lists (conses) and strings it tells if their elements

For Example:

(equal 4 4) T

(equal (+ 2 2) 4) T

Now note a **difference**

(eql (cons 'a 'b) (cons 'a 'b)) NIL

(equal (cons 'a 'b) (cons 'a 'b)) T ; *equal is usually true for things that print the same*

equalpis like equal, just more advanced. Comparison of numbers is type insensitive. Comparison of chars and strings is case insensitive.

For Example:

(equalp (cons 'a 'b) (cons 'a 'b)) T ;*same as equal*

Now note a **difference**

equal(4 4.0) NIL

equalp(4 4.0) T ; *As equalp treats numbers type insensitively*

...