Subject: 27.0.50; `plist-get', `equal' etc. and circular "lists"

From: Paul Eggert <[email-masked]>
Date: Thu, 27 Jun 2019 15:51:37 -0700

> I don't understand why the last two lines are there.

I thought those lines were needed to avoid an infinite loop in 
pathological cyclic cases. But on further thought you're right, they 
aren't needed. I installed that patch; thanks.

> shouldn't `equal' be symmetric?

Yes, on its domain. But circular lists are outside its domain, and the 
documentation doesn't promise any particular behavior on them. It's OK 
if (equal a b) signals an error and (equal b a) does not. It's even OK 
if (equal a b) signals an error and a later call (equal a b) with 
exactly the same (unchanged) arguments does not (because the stack 
happens to have more room the second time). We still have symmetry in 
the sense that (eq (equal a b) (equal b a)) always either returns t or 
signals an error; it never returns nil.

I installed the attached doc patch to try to make this a bit clearer.
>From bdbb390ffef9f8b4eab263055723b27edad7b91c Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Thu, 27 Jun 2019 15:39:04 -0700
Subject: [PATCH] =?UTF-8?q?Improve=20=E2=80=98equal=E2=80=99=20and=20array?=
 =?UTF-8?q?=20doc?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* doc/lispref/objects.texi (Array Type): Array sizes are
nonnegative fixnums, not arbitrary integers.
(Equality Predicates): Do not say that ‘eq’ equals ‘=’ on bignums.
Do not imply that ‘equal’ must signal an error on circular lists.
---
 doc/lispref/objects.texi | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi
index 745baacc29..2e8e2ee714 100644
--- a/doc/lispref/objects.texi
+++ b/doc/lispref/objects.texi
@@ -964,7 +964,8 @@ Array Type
 
   A string is an array of characters and a vector is an array of
 arbitrary objects.  A bool-vector can hold only @code{t} or @code{nil}.
-These kinds of array may have any length up to the largest integer.
+These kinds of array may have any length up to the largest fixnum,
+subject to system architecture limits and available memory.
 Char-tables are sparse arrays indexed by any valid character code; they
 can hold arbitrary objects.
 
@@ -2085,7 +2086,7 @@ Equality Predicates
 This function returns @code{t} if @var{object1} and @var{object2} are
 the same object, and @code{nil} otherwise.
 
-If @var{object1} and @var{object2} are integers with the same value,
+If @var{object1} and @var{object2} are fixnums with the same value,
 they are considered to be the same object (i.e., @code{eq} returns
 @code{t}).  If @var{object1} and @var{object2} are symbols with the
 same name, they are normally the same object---but see @ref{Creating
@@ -2095,7 +2096,7 @@ Equality Predicates
 are the same object, meaning that a change in the contents of one will
 be reflected by the same change in the contents of the other.
 For other types of objects whose contents cannot be changed (e.g.,
-floats), two arguments with the same contents might or might not be
+bignums and floats), two arguments with the same contents might or might not be
 the same object, and @code{eq} returns @code{t} or @code{nil}
 depending on whether the Lisp interpreter created one object or two.
 
@@ -2258,7 +2259,7 @@ Equality Predicates
 their textual contents are the same.
 @end defun
 
-  The test for equality is implemented recursively; for example, given
+  For @code{equal}, equality is defined recursively; for example, given
 two cons cells @var{x} and @var{y}, @code{(equal @var{x} @var{y})}
 returns @code{t} if and only if both the expressions below return
 @code{t}:
@@ -2268,8 +2269,10 @@ Equality Predicates
 (equal (cdr @var{x}) (cdr @var{y}))
 @end example
 
-Because of this recursive method, circular lists may therefore cause
-infinite recursion (leading to an error).
+Comparing circular lists may therefore cause deep recursion that leads
+to an error, and this may result in counterintuitive behavior such as
+@code{(equal a b)} returning @code{t} whereas @code{(equal b a)}
+signals an error.
 
 @defun equal-including-properties object1 object2
 This function behaves like @code{equal} in all cases but also requires
-- 
2.21.0