all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Paul Eggert <eggert@cs.ucla.edu>
To: "Mattias Engdegård" <mattiase@acm.org>
Cc: Pip Cet <pipcet@gmail.com>, Emacs developers <emacs-devel@gnu.org>
Subject: Re: Bug#38708: eq vs eql in byte-compiled code
Date: Thu, 2 Jan 2020 00:38:18 -0800	[thread overview]
Message-ID: <22304b46-55df-578d-7ce5-97c8b60f684e@cs.ucla.edu> (raw)
In-Reply-To: <E783F93A-915D-4467-B308-17AC32639B35@acm.org>

[-- Attachment #1: Type: text/plain, Size: 1991 bytes --]

On 1/1/20 4:38 AM, Mattias Engdegård wrote:

> The flonum/bignum deduplication patch is only in master at this point. If you think it emacs-27 would benefit from a version of it that specifically excludes flonums, this could of course be arranged.

This depends on how important we want (eq integer integer) to work in Emacs 27
as it did in Emacs 26. If it's important, then we hash-cons bignums in Emacs 27
(using a patch like the one I just emailed you), and in that case the
flonum/bignum deduplication patch does not matter for bignums. If it's not
important, then I'd say the flonum/bignum deduplication patch is not urgent
enough to put into Emacs 27.

> The standard rule should be not to use 'eq' for numbers of any kind.

The manual already says this:

To test numbers for numerical equality, you should normally use
@code{=} instead of non-numeric comparison predicates like @code{eq},
@code{eql} and @code{equal}.

> Attached is a proposed documentation patch for emacs-27. While not perfect, it should at least be an improvement (and fixes at least one error).

I found that a bit too dogmatic about avoiding eq on numbers, as it's reasonable
to use eq in many cases (I do it in my code, you do it in your code, and as long
as you know what you're doing it's OK). How about the attached patch instead?
(It does not assume the global bignum deduplication patch.)

>> How about going a bit further, and globally deduplicating all flonums and
>> bignums that result from low-level text-to-number conversion and module imports?
>> That conversion is slow and/or rare already, and if we're lucky deduplication
>> wouldn't make things noticeably slower and wouldn't be much work.
> 
> Maybe, but wouldn't that slow down reading .elc files (and still not shorten individual constant vectors)?

Almost surely it would, yes. I don't know how important that would be. Perhaps
we'd get performance back elsewhere. Only one way to find out, I suppose....

[-- Attachment #2: doc.diff --]
[-- Type: text/x-patch, Size: 3852 bytes --]

diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi
index e952980f26..c8941eab73 100644
--- a/doc/lispref/numbers.texi
+++ b/doc/lispref/numbers.texi
@@ -39,8 +39,8 @@ Integer Basics
   Under the hood, though, there are two kinds of integers: smaller
 ones, called @dfn{fixnums}, and larger ones, called @dfn{bignums}.
 Some functions in Emacs accept only fixnums.  Also, while fixnums can
-always be compared for numeric equality with @code{eq}, bignums
-require more-heavyweight equality predicates like @code{eql}.
+be compared for numeric equality with @code{eq}, bignums require
+more-heavyweight equality predicates like @code{eql} and @code{=}.
 
   The range of values for bignums is limited by the amount of main
 memory, by machine characteristics such as the size of the word used
diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi
index 4be2eb6918..1c4e7e4d4e 100644
--- a/doc/lispref/objects.texi
+++ b/doc/lispref/objects.texi
@@ -266,8 +266,8 @@ Integer Type
   Bignums can have arbitrary precision.  Operations that overflow a
 fixnum will return a bignum instead.
 
-  Fixnums can be compared with @code{eq}, but bignums require
-@code{eql} or @code{=}.  To test whether an integer is a fixnum or a
+  All numbers can be compared with @code{eql} or @code{=}; fixnums can
+also be compared with @code{eq}.  To test whether an integer is a fixnum or a
 bignum, you can compare it to @code{most-negative-fixnum} and
 @code{most-positive-fixnum}, or you can use the convenience predicates
 @code{fixnump} and @code{bignump} on any object.
@@ -2167,17 +2167,20 @@ 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 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
+If @var{object1} and @var{object2} are symbols with the
 same name, they are normally the same object---but see @ref{Creating
-Symbols} for exceptions.  For other types (e.g., lists, vectors,
+Symbols} for exceptions.  For other non-numeric types (e.g., lists, vectors,
 strings), two arguments with the same contents or elements are not
 necessarily @code{eq} to each other: they are @code{eq} only if they
 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.,
-bignums and floats), two arguments with the same contents might or might not be
+
+If @var{object1} and @var{object2} are numbers with differing types or values,
+then they cannot be the same object and @code{eq} returns @code{nil}.
+If they are fixnums with the same value,
+then they are the same object and @code{eq} returns @code{t}.
+If they were computed separately but happen to have the same value
+and the same non-fixnum numeric type, then they 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.
 
@@ -2188,26 +2191,25 @@ Equality Predicates
 @end group
 
 @group
-(eq 456 456)
+(eq ?A ?A)
      @result{} t
 @end group
 
 @group
 (eq 3.0 3.0)
      @result{} t @r{or} nil
-;; @r{The result is implementation-dependent.}
+;; @r{Equal floats may or may not be the same object.}
 @end group
 
 @group
-(eq "asdf" "asdf")
+(eq (make-string 3 ?A) (make-string 3 ?A))
      @result{} nil
 @end group
 
 @group
-(eq "" "")
-     @result{} t
-;; @r{This exception occurs because Emacs Lisp}
-;; @r{makes just one multibyte empty string, to save space.}
+(eq "asdf" "asdf")
+     @result{} t @r{or} nil
+;; @r{Equal string constants or may not be the same object.}
 @end group
 
 @group

  reply	other threads:[~2020-01-02  8:38 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-31 15:07 Bug#38708: eq vs eql in byte-compiled code Pip Cet
2019-12-31 15:51 ` Andrea Corallo
2019-12-31 16:05 ` Mattias Engdegård
2019-12-31 17:38 ` Paul Eggert
2020-01-01 12:38   ` Mattias Engdegård
2020-01-02  8:38     ` Paul Eggert [this message]
2020-01-02 17:26       ` Mattias Engdegård
2020-01-04 19:55         ` Stefan Monnier
2020-01-22 10:56       ` Mattias Engdegård
2020-01-25  0:59         ` Paul Eggert
2020-01-01 15:45   ` Stefan Monnier
2020-01-02  7:52     ` Paul Eggert
2020-01-02 12:27       ` Pip Cet
2020-01-02 23:12         ` Paul Eggert
2020-01-02 13:48       ` Eli Zaretskii
2020-01-04 18:54       ` Stefan Monnier
2020-01-04 19:33         ` Paul Eggert
2020-01-04 19:49           ` Stefan Monnier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=22304b46-55df-578d-7ce5-97c8b60f684e@cs.ucla.edu \
    --to=eggert@cs.ucla.edu \
    --cc=emacs-devel@gnu.org \
    --cc=mattiase@acm.org \
    --cc=pipcet@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.