From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.devel Subject: Re: [Emacs-diffs] master 37940b3: min and max now return one of their arguments Date: Wed, 08 Mar 2017 17:54:26 +0200 Message-ID: <83efy7hih9.fsf@gnu.org> References: <20170307012700.3354.30219@vcs0.savannah.gnu.org> <20170307012701.1C05D23F1F@vcs0.savannah.gnu.org> Reply-To: Eli Zaretskii NNTP-Posting-Host: blaine.gmane.org X-Trace: blaine.gmane.org 1488988545 16968 195.159.176.226 (8 Mar 2017 15:55:45 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Wed, 8 Mar 2017 15:55:45 +0000 (UTC) Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org To: Paul Eggert Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Mar 08 16:55:38 2017 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cldw2-000367-A9 for ged-emacs-devel@m.gmane.org; Wed, 08 Mar 2017 16:55:30 +0100 Original-Received: from localhost ([::1]:57080 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cldw8-0001lG-7K for ged-emacs-devel@m.gmane.org; Wed, 08 Mar 2017 10:55:36 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:34375) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cldvT-0001jn-Bg for emacs-devel@gnu.org; Wed, 08 Mar 2017 10:54:56 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cldvQ-0007Y3-A4 for emacs-devel@gnu.org; Wed, 08 Mar 2017 10:54:55 -0500 Original-Received: from fencepost.gnu.org ([2001:4830:134:3::e]:59015) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cldvQ-0007Xw-6N; Wed, 08 Mar 2017 10:54:52 -0500 Original-Received: from 84.94.185.246.cable.012.net.il ([84.94.185.246]:1322 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1cldvP-0000pk-EF; Wed, 08 Mar 2017 10:54:51 -0500 In-reply-to: (message from Paul Eggert on Tue, 7 Mar 2017 22:08:39 -0800) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2001:4830:134:3::e X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:212839 Archived-At: > From: Paul Eggert > Date: Tue, 7 Mar 2017 22:08:39 -0800 > > Stefan Monnier wrote: > > I'm wondering what is the motivation for this change. > > It avoids nonsensical behavior where 'min' and 'max' were inconsistent with '<' and '>'. Before the patch, (max A B) could return A even when (< A B) returned t. For example: > > (let* ((a 1e16) > (b (1+ (floor a)))) > (list a b (max a b) (< a b) (if (< a b) b a))) > > returned (1e+16 10000000000000001 1e+16 t 10000000000000001) on a 64-bit GNU/Linux host just before the patch was applied. That's because you recently changed how '<' works; before those changes, '<' would report that a is neither less nor greater than b, and thus was consistent with 'max'. With a binary from last month, I get this: (1e+16 10000000000000001 1e+16 nil 1e+16) which shows that '<' and 'max' were consistent then. > In this example, '<' is behaving correctly since A is less than B, and 'max' is behaving incorrectly since it is returning the lesser of A and B. (Come to think of it, this example is clearer than what's in etc/NEWS, so I'll update etc/NEWS.) See above: this example will not necessarily make sense to someone who upgrades from Emacs 25. > In the old days Emacs could assume that every Emacs integer had an exact floating-point representation, so it was OK for functions like '<' and 'max' to convert integer arguments to floating-point before doing their comparisons since these conversions could not lose information. This is no longer true, and the low-level code now needs to be more careful when comparing fixnums to floats. I'm not sure I like these changes in behavior. Don't programmers assume in general that comparisons between values some of which are floats are always done after converting _all_ values to the floating-point representation? I, FWIW, do expect that, but maybe Lisp programmers whose background is not C or Fortran don't. In those other languages, the above values of a and b cannot be meaningfully compared in double floating-point representation, because the relative difference between them is less than the machine epsilon. IOW, these two values are equal when represented as doubles. Under this POV, programs that want to take advantage of a wider integer data type are supposed to manually convert them to integers, e.g. with 'floor', before comparing or taking their 'max'. Your changes break those expectations. For example, the following C program #include int main (void) { double a = 1.e16; long long b = 10000000000000001LL; if (a < b) printf ("a < b\n"); else if (a > b) printf ("a > b\n"); else printf ("a = b\n"); return 0; } prints "a = b". After your changes, the equivalent Lisp program will behave differently. Is this a good idea? P.S. I find the commentary in 'arithcompare' not detailed enough to explain to a casual reader some tricky code such as this: i1 = f2 = i2 = XINT (num2); fneq = f1 != f2; The general idea is explained, but the devil is in the details, and those are not commented at all. Please consider adding more explanations, so that the implementation becomes easier to grasp. I don't think it's a good idea to have our code present puzzles to the reader, especially a reader who is not privy to the subtleties of FP calculations. TIA.