Equality

<-Previous | ^UP^ | Next->

Lisp defines 4 generic equality predicates. In order of "strictness" they are:

  • eq
  • eql
  • equal
  • equalp
When we say eq is the strictest test, we mean that it is most likely to return NIL. So any two items which compare as T with eq will certainly compare as T with eql and with all the other equality predicates below eql in the stack. A similar relationship may be drawn between eql and equal, and likewise between equal and equalp. Now we will show some examples and describe the characteristics of each of these equality predicates.

eq

eq takes 2 objects as arguments and returns t if they are identical
Integers and Characters have the same symbol-name and value, so when comparing Integers and Characters, whilst it may appear eq is testing for value equality, it is in fact testing for object equality.
eq is fast but is only safe to use when the types (i.e. classes) of the objects being tested are known in advance

GDL-USER> ((eq 1 1)

T

GDL-USER> (eq #\a #\a)

T

Floats, lists, and strings however are just pointers to the actual objects containing the value in memory, so eq will generally return NIL if either of the objects being tested is a float, list or string. This is because two floats, lists, or strings, even though they may appear to be identical, typically are existing in two different places in memory.

GDL-USER> (eq 1.0 1.0)

NIL

GDL-USER> (eq "a" "a")

NIL

GDL-USER> (eq (list 1 2 3) (list 1 2 3))

NIL

GDL-USER> (eq 1 1.0)

NIL

eql

eql behaves as eq except it guarantees to consider 2 objects of the same class representing the same numeric or character value to be equal

GDL-USER> (eql 1.0 1.0)

T

GDL-USER> (eql "a" "a")

NIL

GDL-USER> (eql (list 1 2 3) (list 1 2 3))

NIL

GDL-USER> (eql 1 1.0)

NIL

equal

equal behaves as eql except different objects may be considered equivalent if their values look the same. This is particularly useful when testing for equality between two strings or two lists

GDL-USER> (equal "a" "a")

T

GDL-USER> (equal (list 1 2 3) (list 1 2 3))

T

GDL-USER> (equal 1 1.0)

NIL

GDL-USER> (equal "A" "a")

NIL

GDL-USER> (equal (list 1 2 3) (list 1 2 3.0))

NIL

equalp

equalp behaves as equal, except numbers are considered equal if they are mathematically equal, and string equality is not case-sensitive

GDL-USER> (equalp 1 1.0)

T

GDL-USER> (equalp "A" "a")

T

GDL-USER> (equalp (list 1 2 3) (list 1 2 3.0))

T

In addition to the above, Lisp defines specific equality tests (predicates) for numbers and strings

Number Comparison

  • < - less than
  • <= - less than or equal
  • = - equal
  • >= - greater than or equal
  • > - greater than
  • /= - not equal

All of these functions take one or more arguments, and with the exception of /=, all make their comparisons between consecutive pairs. With /=, it compares all posible combinations of the arguments

GDL-USER> (> 5 4 3)

T

GDL-USER> (> 5 4 5)

NIL

GDL-USER> (/= 1 2 3 4)

T

GDL-USER> (/= 1 1 4 1)

NIL

Specific tests for number values are also avaliable

  • zerop - the number is zero
  • plusp - the number is greater than zero
  • minusp - the number is less than zero

When comparing Float numbers, it is better to use the GendL functions near-to? and near-zero?. These return T if the two arguments are within *ZERO-EPSILON* of each other

String Comparison

string comparison is similar number comparison, except there is one variant (the first shown below) which is case-sensitive and one (the second) which is case-insentitive. These functions accept two string arguments.

  • string<, string-lessp - one string less than another
  • string=, string-equal - one string equal to another
  • string>, string-greaterp - one string greater than another
  • string/=, string-not-equal - strings are not equal

These functions also have keyword inputs (:start1 :end1 :start2 and :end2) to enable substrings of the supplied strings to be compared

Object Type

Finally, Lisp defines predicates to test for object type

  • numberp - returns T if the object is a number.
  • floatp - returns T if the object is a float.
  • stringp - returns T if the object is a string.
  • characterp - returns T if the object is a character.
  • listp - returns T if the object is a list.

Resources

equality.lisp