Equality and Identity

Lispex separates atom/identity equality (`eq?`, `eqv?`), deep structural equality (`equal?`), and numeric equality (`=`).

When this matters

Pick equality by intent, not habit: mathematical equality for numbers, identity-style equality for atoms or the same aggregate object, and deep equality for data structures.

See it run

LISPEX
(list (= 2 2.0) (eqv? 2 2.0) (equal? (list 1 2) (list 1 2)))

Observed result

OUTPUT
(#t #f #t)

Read the example

= treats exact 2 and inexact 2.0 as the same mathematical number. eqv? preserves the exactness distinction. Two separately constructed lists are not the same object, but equal? sees the same contents.

How to reason about it

  • eq? and eqv? agree on atoms in this profile and compare aggregates by identity.
  • eqv? and equal? are exactness-sensitive: exact 2 and inexact 2.0 are different.
  • equal? descends through pairs, vectors, bytevectors, and strings with cycle detection.

Choose quickly

PredicateUse it forAggregate behavior
=numbers with mathematical equalitynon-numbers are a domain error
eq?atoms and object identitysame aggregate object only
eqv?exactness-sensitive atoms and identitysame aggregate object only
equal?nested data contentsrecursive, cycle-safe structural comparison
== / !=readable structural aliasesequal? and its negation

A common mistake

= accepts numbers only; == and != are structural aliases.

Current boundaries

  • Procedure equality never compares procedure bodies structurally.

Keep going

Data Types explains which values have identity. Aggregate Procedures shows the constructors that create separate objects.

Data types · Aggregate procedures