From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Pip Cet Newsgroups: gmane.emacs.bugs Subject: bug#38708: [PATCH] Deduplicate flonum and bignum constants in bytecode Date: Sun, 29 Dec 2019 17:29:52 +0000 Message-ID: References: <096F68FE-0CB3-45CD-AB14-89BB5447484C@acm.org> Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="135861"; mail-complaints-to="usenet@blaine.gmane.org" Cc: 38708@debbugs.gnu.org To: Mattias =?UTF-8?Q?Engdeg=C3=A5rd?= Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sun Dec 29 18:31:17 2019 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1ilcPM-000Z8R-6f for geb-bug-gnu-emacs@m.gmane.org; Sun, 29 Dec 2019 18:31:16 +0100 Original-Received: from localhost ([::1]:53876 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ilcPL-0005Uv-0G for geb-bug-gnu-emacs@m.gmane.org; Sun, 29 Dec 2019 12:31:15 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:43316) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ilcPA-0005OJ-Du for bug-gnu-emacs@gnu.org; Sun, 29 Dec 2019 12:31:05 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ilcP8-0000Gn-Qj for bug-gnu-emacs@gnu.org; Sun, 29 Dec 2019 12:31:04 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:54202) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ilcP8-0000GM-Mw for bug-gnu-emacs@gnu.org; Sun, 29 Dec 2019 12:31:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1ilcP8-0002Pl-Ks for bug-gnu-emacs@gnu.org; Sun, 29 Dec 2019 12:31:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Pip Cet Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 29 Dec 2019 17:31:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 38708 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 38708-submit@debbugs.gnu.org id=B38708.15776406367836 (code B ref 38708); Sun, 29 Dec 2019 17:31:02 +0000 Original-Received: (at 38708) by debbugs.gnu.org; 29 Dec 2019 17:30:36 +0000 Original-Received: from localhost ([127.0.0.1]:60169 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ilcOh-00021r-Ch for submit@debbugs.gnu.org; Sun, 29 Dec 2019 12:30:35 -0500 Original-Received: from mail-ot1-f53.google.com ([209.85.210.53]:39339) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ilcOf-0001wL-Qj for 38708@debbugs.gnu.org; Sun, 29 Dec 2019 12:30:34 -0500 Original-Received: by mail-ot1-f53.google.com with SMTP id 77so43292769oty.6 for <38708@debbugs.gnu.org>; Sun, 29 Dec 2019 09:30:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=dtroDKZAklyDwCPitbzIGOVb7KNIIxpGxLzlCLKiwn4=; b=c28+hiL7w8QeKWxsmAfW+Uf7OoRaNvIxw8YdginWa2Q5vkMcSMhcTfqd+bFR+Co84B K5pjisNIGifrlr/XsVRyHqVvuI2xqlZkJeP4xThRHDp7F2qnelHduc7hVjfq3IVFwcEC Hx5KVNjCBelS6/8Vqw3aBUQTTJ8V5KSXBDCiwjImlfoSDu14C5Y0JlS7dMSvEluWXsQL YCu4XEUOfPeQttaHudPEw4X6xnOP7TrMPdC8a0ylqhVj2WVTa+Kcv/ZQnPWI87L1rdcM OcrrGCmmJMWkNvdRoZxDi2tIWBAbf1hbDWNhcATwvoLp2nWQRhlh9PDvDaPNKxoMSWBv y+8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=dtroDKZAklyDwCPitbzIGOVb7KNIIxpGxLzlCLKiwn4=; b=ZrF/eRCqUHNWx35Gx/mE3uOLSmByGRXp3Um61geU9jAyaQA3izUf4rh0Rc5eyMQkdl CoYfqC3tF77J6uEsVTBYMOgBmmYbaRAa8VmaRogtdSVA2tMYisG7eJ3e6gNYTmSfy0Y8 zjhkOV3BwUmDYI8ELZeB0dY5d7mpSK/JxX2aXg1FrH87GC1Y08BARCZZKimldK4QOHHs QThKigj0LJqPeNoeSlwtC48uTNAQj4Mokb9TjGVC2sdtQ4i288HwleyFC8W91D0kLe8S 89zqTttluhvZMgbwVnb1aswd3z40GrJQ0mG+7gEs4cZNWq/wz7TM2DCcUWDIha7S//rJ 9+jA== X-Gm-Message-State: APjAAAWZ415m+kCC8a6l8dVvTSk1Q589Ei7niBJoaEAWR1O6fsMeoywx 8GAnLjJbv1SW3V4oW/5dNfBvpoRMubKPdYrQYnM= X-Google-Smtp-Source: APXvYqwV3fZsfHJmb6ZN+tRG3kE9VFFN+/JHpEjtXmUsYzenikqT+exusk7FxjOEatuwgA/mcRWjpv6st6wDm6Kskbw= X-Received: by 2002:a9d:4805:: with SMTP id c5mr33936317otf.292.1577640628211; Sun, 29 Dec 2019 09:30:28 -0800 (PST) In-Reply-To: X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:173896 Archived-At: On Sat, Dec 28, 2019 at 6:50 PM Mattias Engdeg=C3=A5rd w= rote: > Elisp has a few 'boundedly undefined' parts which would be avoided in a g= reenfield design but that we are more or less stuck with for the time being= , and probably should paint in large letters on the first page of the manua= l. Such as: don't use eq for numbers; don't mutate literals (strings, conse= s, vectors); etc. I don't think we're stuck with those two, and I don't think we should be making them worse than they already are (in Emacs 26.3). Sorry, the rest of this got a bit long. I think your change isn't as trivial as it seems at first glance, and we shouldn't do it for Emacs 27, but it's fine on the master branch and might help us shake out some bugs (and, strategically, the paradoxical behavior observed with your patch is a good argument for making eq and eql synonymous). > In my experience people seem to have little trouble understanding that eq= shouldn't be used to compare numbers. Not my experience. In fact, anyone who reads https://www.gnu.org/software/emacs/manual/html_mono/elisp.html#Equality-Pre= dicates today would come away with the reassuring knowledge that "If object1 and object2 are integers with the same value, they are considered to be the same object (i.e., eq returns t)." And there's plenty of code that uses eq to compare numbers, on the master branch, today. So whether you learn by experience or by "stable" documentation, you'll pick up the habit of comparing integers with eq. > If anything, the introduction of bignums helps driving the point home: up= to and including Emacs 26, elisp programmers could get away with eq for in= tegers but not floating-point numbers. Now, the rules are simpler. (Charact= ers still get a free pass, I suppose.) What are the rules, then? "Use eql, except if you're comparing against a small integer, when eq is fine, or a character, which might not be that small but will be fine, or a number you know from studying the Emacs internals is a fixnum"? > While we could document a safe range of fixnums for which eq applies, it'= s probably better not to. My impression was people were very careful to use eq and EQ whenever they could prove the numbers were still in fixnum range. > > Technically, I think code such as > > > > (cond ((eq a b) 1) ((not (eq a b)) 2) (t 3)) > > > > is allowed to return 3. We should attempt not to make changes that > > make this more likely, though. > > Given the state of elisp byte-code optimisation, there is plenty of room = for improvements before such semantics become unavoidable. In particular, t= he committed change does not in any way enable such paradoxical behaviour. (defun f () (cond ((eq 1.0 1.0) 1) ((my-not-eq 1.0 1.0) 2) (t 3)))) produces 3 here, with your patch and standard byte compilation. That seems just as paradoxical to me. (You're right about hash tables). > > You're right, that is eq's contract. But people do misuse it, and one > > of the things they wouldn't expect is that optimization results in > > things becoming non-eq that were eq before optimization; I think the > > other direction is much less problematic. > > Good thing that the change works in that other direction then! Sorry, I may have been ambiguous: With your patch, (eq 1.0 1.0) is t without optimization, nil with optimization. That's the direction I meant. > >> What would anyone gain from such a restriction? And the change is mino= r because it's a small thing to do; what I thought looked like an obvious o= versight, or one that made more sense back when Elisp didn't have bignums. > > > > Well, Elisp has had floats for a while, and bignum constants appear to > > be nonexistent, so far. > > In other words, there is no broken bignum code that can break. Sorry, that was a response to the second part: the original code makes just as much sense now as it did in the pre-bignum age. You're right that folding floats but not bignums is probably a bad idea. This probably isn't leading anywhere, but I still think this snippet of code is somewhat realistic and should never output "1 nil". First we count the number of eq-distinct elements, then we check whether the elements are eq-distinct. (defun count-distinct-elements (&rest args) (let ((ht (make-hash-table :test 'eq))) (dolist (arg args) (puthash arg 1 ht)) (hash-table-count ht))) (defmacro f (x y) `(format "%S %S" (count-distinct-elements ,x ,y) (eq ,x ,y))) (defun g () (f 1.0 1.0))