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?
From Common Lisp: Equality Predicates
(eq x y)
is true if and only ifx
andy
are the same identical object.The
eql
predicate is true if its arguments areeq
, 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 allequalp
.
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.
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.
From here and my teacher's slides
eq tests 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
eql first 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.
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). 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
equalp is 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
© 2022 - 2024 — McMap. All rights reserved.