# “(equal a b)⇒t” whereas “(equal b a)⇒error”

GNU Emacs Lisp Reference Manual, 2.8 Equality Predicates:

Comparing circular lists may therefore cause deep recursion that leads to an error, and this may result in counterintuitive behavior such as `(equal a b)` returning `t` whereas `(equal b a)` signals an error.

I've found a case:

``````ELISP> (setq a '#1=(t .  #1#)
b    `(t t . ,a))
ELISP> (equal b a)
t
ELISP> (equal a b)
*** Eval error ***  List contains a loop: #1=(t . #1#)
ELISP>
``````

Does Elisp test `eq` first when testing `equal`?
If so, I don't think `(equal a b)` will signal an error.

I mean,

``````a: t ---
^    |
|    |
----
b: t -> t -> t ---
^    |  This loop is `a`.
|    |
----
``````

when testing whether `a` `eq`s `b`:

1. `a` and `b` are not the same obj (i.e. not `eq`)
2. so test their first element, and `t` `eq`s `t`; then test their CDRs
3. `a`'s CDR and `b`'s CDR are not the same obj
4. so test CDRs' first element, and `t` `eq`s `t`; then test CDRs' CDRs
5. `a` `eq`s `a`

so I think `(equal a b)` should return `t`.

Where is my mistake?

Great question!

Emacs detects the circularity of `a` and reports it before it descends far enough into `b` to discover that they are `equal`.

The reason for the asymmetry is that Emacs only has to check for circularity of one argument, not both.

Does Elisp test `eq` first when testing `equal`?

Yes, of course.

• @Shynur: Let's remove the comments - their gist is now in the answer.
– sds
Jan 13, 2023 at 14:28