Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between eq, eql, equal and equalp, in Common Lisp?

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?

like image 933
Cristián Romo Avatar asked Feb 13 '09 19:02

Cristián Romo


People also ask

What is equal in Lisp?

eql is the default equality test in Common Lisp (for operators that take sequences as arguments). equal is 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).

What is an equality predicate?

Equality predicates tell whether one value is "the same as" another. There are actually several important senses of "the same as," so Scheme provides four equality predicates. Sometimes you want to know whether two data structures are structurally the same, with the same values in the same places.

How do you compare numbers in Lisp?

Compatibility note: In Common Lisp, the comparison operations perform ``mixed-mode'' comparisons: (= 3 3.0) is true. In MacLisp, there must be exactly two arguments, and they must be either both fixnums or both floating-point numbers. To compare two numbers for numerical equality and type equality, use eql.

How do you check for string equality in a lisp?

[Function]string= compares two strings and is true if they are the same (corresponding characters are identical) but is false if they are not.


2 Answers

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. 
like image 72
Bill the Lizard Avatar answered Oct 19 '22 01:10

Bill the Lizard


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.

like image 35
Leslie P. Polzer Avatar answered Oct 19 '22 02:10

Leslie P. Polzer