unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: "Basil L. Contovounesios" <contovob@tcd.ie>
To: Eli Zaretskii <eliz@gnu.org>
Cc: eggert@cs.ucla.edu, emacs-devel@gnu.org
Subject: Re: Predicate for true lists
Date: Mon, 09 Jul 2018 22:25:43 +0300	[thread overview]
Message-ID: <87sh4s9poo.fsf@tcd.ie> (raw)
In-Reply-To: <83h8lcnbxb.fsf@gnu.org> (Eli Zaretskii's message of "Fri, 6 Jul 2018 08:57:52 +0300")

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

Hmm, I thought I had already sent my reply to this, but I don't see it
anywhere; I must have dreamt it.

Eli Zaretskii <eliz@gnu.org> writes:

>> >From f42cb45f449dbb6c3d806398a128bc5914fdebab Mon Sep 17 00:00:00 2001
>> From: "Basil L. Contovounesios" <contovob@tcd.ie>
>> Date: Fri, 6 Jul 2018 00:41:11 +0300
>> Subject: [PATCH 1/3] Add convenience function proper-list-length
>> 
>> * lisp/subr.el (proper-list-length): New function.
>> Suggested by Paul Eggert <eggert@cs.ucla.edu> in
>> https://lists.gnu.org/archive/html/emacs-devel/2018-06/msg00138.html.
>> * doc/lispref/lists.texi (List Elements):
>> * etc/NEWS: Mention it.
>
> The "it" part here is ambiguous, because it's too far from the last
> place where the function's name was mentioned.  Please state the name
> of the function for better readability.
>
>> * lisp/emacs-lisp/byte-opt.el (byte-optimize-if):
>> * lisp/emacs-lisp/cl-macs.el (cl--make-usage-args):
>> * lisp/org/ob-core.el (org-babel-insert-result): Use it.
>
> Likewise.
>
>> * lisp/emacs-lisp/ert.el (ert--proper-list-p): Remove.
>> (ert--explain-equal-rec): Use proper-list-length instead.
>> * lisp/format.el (format-proper-list-p): Remove.
>
> Maybe consider mentioning that these are removed "because
> SUCH-AND-SUCH replaces them in file FOO."
>
>> +@defun proper-list-length object
>> +This function returns the length of @var{object} if it is a proper
>> +list, @code{nil} otherwise.  In addition to satisfying @code{listp}, a
>> +proper list is neither circular nor dotted.
>
> Proper list is defined elsewhere in the manual, so please add here a
> cross-reference to that spot (I'd suggest doing that with @pxref in
> parentheses at the end of the first sentence).

Done x4.

>> +** New function 'proper-list-length'.
>> +Given a proper list as argument, this function returns its length;
>> +otherwise, it returns nil.  This function can thus be used as a
>> +predicate for proper lists.
>
> Do we really want this usage of the function as a predicate?  I find
> this slightly unnatural, and also not future-proof enough, because you
> rely on the checks 'length' does internally.  If the internals of
> 'length' change one day, this predicate usage will collapse like a
> house of cards.  Would it make more sense to have a separate
> predicate?

My reading of the ensuing subthread is that it is okay to define
proper-list-p such that it relies on Flength's now-documented error
behaviour to return a proper list's length.

The only alternative I can think of (which avoids traversing a list
twice) is to write proper-list-p in C by duplicating the relevant parts
of Flength's current behaviour.  Any preferences?

By the way, is proper-list-p preferred over list-proper-p?

>> +(defun proper-list-length (object)
>> +  "Return OBJECT's length if it is a proper list, nil otherwise.
>> +A proper list is neither circular nor dotted (i.e., its last cdr
>> +is nil)."
>
> But if we do want to use this as a predicate, then the doc string
> should say so.

This isn't necessary if the function is called proper-list-p and is
documented under '(elisp) List-related Predicates', right?

>> * doc/lispref/lists.texi (Cons Cells, Building Lists):
>> * doc/lispref/sequences.texi (Vector Functions): Do it.
>
> Please put the full description in the log entry.  "Do it" refers to
> what the header says, I presume, but I at least am used to ignoring
> the headers and reading the entries, because they are generally more
> informative (due to space constraints on the header).

Done.

>> +@cindex proper list
>>  @cindex true list
>>    Also by convention, the @sc{cdr} of the last cons cell in a list is
>>  @code{nil}.  We call such a @code{nil}-terminated structure a
>> -@dfn{true list}.  In Emacs Lisp, the symbol @code{nil} is both a
>> +@dfn{proper list}.  In Emacs Lisp, the symbol @code{nil} is both a
>
> We still have "true list" in the index (and rightly so), so I think
> the new text should say, perhaps in parens or in a footnote, that such
> lists are also known as "true lists".  Imagine a reader who follows
> the "true list" index entry and gets placed on this text -- they will
> be confused to not see "true list" mentioned anywhere.  Besides, that
> term is in wide usage elsewhere.

Done as a footnote in the style of the first one under
'(elisp) Intro Eval'.

I reattach the three patches, updated also for Paul's feedback in
https://lists.gnu.org/archive/html/emacs-devel/2018-07/msg00149.html.

Thanks!

-- 
Basil


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-predicate-proper-list-p.patch --]
[-- Type: text/x-diff, Size: 12067 bytes --]

From d530bcf1d59a01d37b22fea6a832f0578198350d Mon Sep 17 00:00:00 2001
From: "Basil L. Contovounesios" <contovob@tcd.ie>
Date: Mon, 9 Jul 2018 18:36:43 +0300
Subject: [PATCH 1/3] Add predicate proper-list-p

For discussion, see emacs-devel thread starting at
https://lists.gnu.org/archive/html/emacs-devel/2018-04/msg00460.html.

* lisp/subr.el (proper-list-p): New function.
Implementation suggested by Paul Eggert <eggert@cs.ucla.edu> in
https://lists.gnu.org/archive/html/emacs-devel/2018-06/msg00138.html.
* doc/lispref/lists.texi (List Elements):
* etc/NEWS: Document proper-list-p.
* lisp/org/ob-core.el (org-babel-insert-result):
* lisp/emacs-lisp/byte-opt.el (byte-optimize-if):
* lisp/emacs-lisp/cl-macs.el (cl--make-usage-args): Use proper-list-p.
* lisp/emacs-lisp/ert.el (ert--proper-list-p): Remove.
Replaced by proper-list-p in lisp/subr.el.
(ert--explain-equal-rec): Use proper-list-length.
* lisp/format.el (format-proper-list-p): Remove.
Replaced by proper-list-p in lisp/subr.el.
(format-annotate-single-property-change): Use proper-list-p.
* test/lisp/emacs-lisp/ert-tests.el (ert-test-proper-list-p):
Move from here...
* test/lisp/subr-tests.el (subr-tests--proper-list-length):
...to here, mutatis mutandis.
---
 doc/lispref/lists.texi            | 16 ++++++++++++
 etc/NEWS                          |  5 ++++
 lisp/emacs-lisp/byte-opt.el       |  2 +-
 lisp/emacs-lisp/cl-macs.el        |  2 +-
 lisp/emacs-lisp/ert.el            | 28 ++++++---------------
 lisp/format.el                    | 12 ++-------
 lisp/org/ob-core.el               |  5 ++--
 lisp/subr.el                      |  6 +++++
 test/lisp/emacs-lisp/ert-tests.el | 42 -------------------------------
 test/lisp/subr-tests.el           | 18 +++++++++++++
 10 files changed, 59 insertions(+), 77 deletions(-)

diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi
index 761750eb20..57cefeac96 100644
--- a/doc/lispref/lists.texi
+++ b/doc/lispref/lists.texi
@@ -153,6 +153,22 @@ List-related Predicates
 @end example
 @end defun
 
+@defun proper-list-p object
+This function returns the length of @var{object} if it is a proper
+list, @code{nil} otherwise (@pxref{Cons Cells}).  In addition to
+satisfying @code{listp}, a proper list is neither circular nor dotted.
+
+@example
+@group
+(proper-list-p '(a b c))
+    @result{} 3
+@end group
+@group
+(proper-list-p '(a b . c))
+    @result{} nil
+@end group
+@end example
+@end defun
 
 @node List Elements
 @section Accessing Elements of Lists
diff --git a/etc/NEWS b/etc/NEWS
index dae028be7b..1a1e0d8b70 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -703,6 +703,11 @@ manual for more details.
 \f
 * Lisp Changes in Emacs 27.1
 
++++
+** New function 'proper-list-p'.
+Given a proper list as argument, this predicate returns its length;
+otherwise, it returns nil.
+
 ** define-minor-mode automatically documents the meaning of ARG
 
 +++
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index 3bc4c438d6..11161647a6 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -983,7 +983,7 @@ byte-optimize-if
   (let ((clause (nth 1 form)))
     (cond ((and (eq (car-safe clause) 'progn)
                 ;; `clause' is a proper list.
-                (null (cdr (last clause))))
+                (proper-list-p clause))
            (if (null (cddr clause))
                ;; A trivial `progn'.
                (byte-optimize-if `(if ,(cadr clause) ,@(nthcdr 2 form)))
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index b50961adac..58eadbade0 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -498,7 +498,7 @@ cl--make-usage-args
       ;; `&aux' args aren't arguments, so let's just drop them from the
       ;; usage info.
       (setq arglist (cl-subseq arglist 0 aux))))
-  (if (cdr-safe (last arglist))         ;Not a proper list.
+  (if (not (proper-list-p arglist))     ; Not a proper list.
       (let* ((last (last arglist))
              (tail (cdr last)))
         (unwind-protect
diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el
index 32bb367cdb..cad21044f1 100644
--- a/lisp/emacs-lisp/ert.el
+++ b/lisp/emacs-lisp/ert.el
@@ -472,18 +472,6 @@ ert--should-error-handle-error
 ;; buffer.  Perhaps explanations should be reported through `ert-info'
 ;; rather than as part of the condition.
 
-(defun ert--proper-list-p (x)
-  "Return non-nil if X is a proper list, nil otherwise."
-  (cl-loop
-   for firstp = t then nil
-   for fast = x then (cddr fast)
-   for slow = x then (cdr slow) do
-   (when (null fast) (cl-return t))
-   (when (not (consp fast)) (cl-return nil))
-   (when (null (cdr fast)) (cl-return t))
-   (when (not (consp (cdr fast))) (cl-return nil))
-   (when (and (not firstp) (eq fast slow)) (cl-return nil))))
-
 (defun ert--explain-format-atom (x)
   "Format the atom X for `ert--explain-equal'."
   (pcase x
@@ -494,17 +482,17 @@ ert--explain-format-atom
 (defun ert--explain-equal-rec (a b)
   "Return a programmer-readable explanation of why A and B are not `equal'.
 Returns nil if they are."
-  (if (not (equal (type-of a) (type-of b)))
+  (if (not (eq (type-of a) (type-of b)))
       `(different-types ,a ,b)
     (pcase-exhaustive a
       ((pred consp)
-       (let ((a-proper-p (ert--proper-list-p a))
-             (b-proper-p (ert--proper-list-p b)))
-         (if (not (eql (not a-proper-p) (not b-proper-p)))
+       (let ((a-length (proper-list-p a))
+             (b-length (proper-list-p b)))
+         (if (not (eq (not a-length) (not b-length)))
              `(one-list-proper-one-improper ,a ,b)
-           (if a-proper-p
-               (if (not (equal (length a) (length b)))
-                   `(proper-lists-of-different-length ,(length a) ,(length b)
+           (if a-length
+               (if (/= a-length b-length)
+                   `(proper-lists-of-different-length ,a-length ,b-length
                                                       ,a ,b
                                                       first-mismatch-at
                                                       ,(cl-mismatch a b :test 'equal))
@@ -523,7 +511,7 @@ ert--explain-equal-rec
                      (cl-assert (equal a b) t)
                      nil))))))))
       ((pred arrayp)
-       (if (not (equal (length a) (length b)))
+       (if (/= (length a) (length b))
            `(arrays-of-different-length ,(length a) ,(length b)
                                         ,a ,b
                                         ,@(unless (char-table-p a)
diff --git a/lisp/format.el b/lisp/format.el
index 2f198e3eb7..1222abbf65 100644
--- a/lisp/format.el
+++ b/lisp/format.el
@@ -539,14 +539,6 @@ format-make-relatively-unique
 	(setq tail next)))
     (cons acopy bcopy)))
 
-(defun format-proper-list-p (list)
-  "Return t if LIST is a proper list.
-A proper list is a list ending with a nil cdr, not with an atom "
-  (when (listp list)
-    (while (consp list)
-      (setq list (cdr list)))
-    (null list)))
-
 (defun format-reorder (items order)
   "Arrange ITEMS to follow partial ORDER.
 Elements of ITEMS equal to elements of ORDER will be rearranged
@@ -1005,8 +997,8 @@ format-annotate-single-property-change
       ;; If either old or new is a list, have to treat both that way.
       (if (and (or (listp old) (listp new))
 	       (not (get prop 'format-list-atomic-p)))
-	  (if (or (not (format-proper-list-p old))
-		  (not (format-proper-list-p new)))
+          (if (not (and (proper-list-p old)
+                        (proper-list-p new)))
 	      (format-annotate-atomic-property-change prop-alist old new)
 	    (let* ((old (if (listp old) old (list old)))
 		   (new (if (listp new) new (list new)))
diff --git a/lisp/org/ob-core.el b/lisp/org/ob-core.el
index 5d5faaa6fd..a5449fe35e 100644
--- a/lisp/org/ob-core.el
+++ b/lisp/org/ob-core.el
@@ -2310,10 +2310,9 @@ org-babel-insert-result
 		       (lambda (r)
 			 ;; Non-nil when result R can be turned into
 			 ;; a table.
-			 (and (listp r)
-			      (null (cdr (last r)))
+                         (and (proper-list-p r)
 			      (cl-every
-			       (lambda (e) (or (atom e) (null (cdr (last e)))))
+                               (lambda (e) (or (atom e) (proper-list-p e)))
 			       result)))))
 		  ;; insert results based on type
 		  (cond
diff --git a/lisp/subr.el b/lisp/subr.el
index ca184d8fc8..c1d90e3fb1 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -555,6 +555,12 @@ zerop
   (declare (compiler-macro (lambda (_) `(= 0 ,number))))
   (= 0 number))
 
+(defun proper-list-p (object)
+  "Return OBJECT's length if it is a proper list, nil otherwise.
+A proper list is neither circular nor dotted (i.e., its last cdr
+is nil)."
+  (and (listp object) (ignore-errors (length object))))
+
 (defun delete-dups (list)
   "Destructively remove `equal' duplicates from LIST.
 Store the result in LIST and return it.  LIST must be a proper list.
diff --git a/test/lisp/emacs-lisp/ert-tests.el b/test/lisp/emacs-lisp/ert-tests.el
index e92b434274..cb957bd9fd 100644
--- a/test/lisp/emacs-lisp/ert-tests.el
+++ b/test/lisp/emacs-lisp/ert-tests.el
@@ -496,48 +496,6 @@ ert-test--which-file
 
 
 ;;; Tests for utility functions.
-(ert-deftest ert-test-proper-list-p ()
-  (should (ert--proper-list-p '()))
-  (should (ert--proper-list-p '(1)))
-  (should (ert--proper-list-p '(1 2)))
-  (should (ert--proper-list-p '(1 2 3)))
-  (should (ert--proper-list-p '(1 2 3 4)))
-  (should (not (ert--proper-list-p 'a)))
-  (should (not (ert--proper-list-p '(1 . a))))
-  (should (not (ert--proper-list-p '(1 2 . a))))
-  (should (not (ert--proper-list-p '(1 2 3 . a))))
-  (should (not (ert--proper-list-p '(1 2 3 4 . a))))
-  (let ((a (list 1)))
-    (setf (cdr (last a)) a)
-    (should (not (ert--proper-list-p a))))
-  (let ((a (list 1 2)))
-    (setf (cdr (last a)) a)
-    (should (not (ert--proper-list-p a))))
-  (let ((a (list 1 2 3)))
-    (setf (cdr (last a)) a)
-    (should (not (ert--proper-list-p a))))
-  (let ((a (list 1 2 3 4)))
-    (setf (cdr (last a)) a)
-    (should (not (ert--proper-list-p a))))
-  (let ((a (list 1 2)))
-    (setf (cdr (last a)) (cdr a))
-    (should (not (ert--proper-list-p a))))
-  (let ((a (list 1 2 3)))
-    (setf (cdr (last a)) (cdr a))
-    (should (not (ert--proper-list-p a))))
-  (let ((a (list 1 2 3 4)))
-    (setf (cdr (last a)) (cdr a))
-    (should (not (ert--proper-list-p a))))
-  (let ((a (list 1 2 3)))
-    (setf (cdr (last a)) (cddr a))
-    (should (not (ert--proper-list-p a))))
-  (let ((a (list 1 2 3 4)))
-    (setf (cdr (last a)) (cddr a))
-    (should (not (ert--proper-list-p a))))
-  (let ((a (list 1 2 3 4)))
-    (setf (cdr (last a)) (cl-cdddr a))
-    (should (not (ert--proper-list-p a)))))
-
 (ert-deftest ert-test-parse-keys-and-body ()
   (should (equal (ert--parse-keys-and-body '(foo)) '(nil (foo))))
   (should (equal (ert--parse-keys-and-body '(:bar foo)) '((:bar foo) nil)))
diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el
index 52b61d9fb9..86938d5dbe 100644
--- a/test/lisp/subr-tests.el
+++ b/test/lisp/subr-tests.el
@@ -306,6 +306,24 @@ subr-test--frames-1
   (should (eq (string-to-char (symbol-name (gensym))) ?g))
   (should (eq (string-to-char (symbol-name (gensym "X"))) ?X)))
 
+(ert-deftest subr-tests--proper-list-p ()
+  "Test `proper-list-p' behavior."
+  (dotimes (length 4)
+    ;; Proper and dotted lists.
+    (let ((list (make-list length 0)))
+      (should (= (proper-list-p list) length))
+      (should (not (proper-list-p (nconc list 0)))))
+    ;; Circular lists.
+    (dotimes (n (1+ length))
+      (let ((circle (make-list (1+ length) 0)))
+        (should (not (proper-list-p (nconc circle (nthcdr n circle))))))))
+  ;; Atoms.
+  (should (not (proper-list-p 0)))
+  (should (not (proper-list-p "")))
+  (should (not (proper-list-p [])))
+  (should (not (proper-list-p (make-bool-vector 0 nil))))
+  (should (not (proper-list-p (make-symbol "a")))))
+
 (ert-deftest subr-tests--assq-delete-all ()
   "Test `assq-delete-all' behavior."
   (cl-flet ((new-list-fn
-- 
2.18.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-Refer-to-proper-lists-instead-of-true-lists.patch --]
[-- Type: text/x-diff, Size: 3791 bytes --]

From a389dc15aba437db38c06d2782e9ad60f3a5496f Mon Sep 17 00:00:00 2001
From: "Basil L. Contovounesios" <contovob@tcd.ie>
Date: Mon, 9 Jul 2018 16:25:12 +0300
Subject: [PATCH 2/3] Refer to "proper lists" instead of "true lists"

* doc/lispref/lists.texi (Cons Cells, Building Lists):
* doc/lispref/sequences.texi (Vector Functions): Use the more
popular term "proper", rather than "true", to qualify nil-terminated
lists.

For discussion, see the following emacs-devel subthreads:
https://lists.gnu.org/archive/html/emacs-devel/2018-06/msg00112.html
https://lists.gnu.org/archive/html/emacs-devel/2018-06/msg00138.html
---
 doc/lispref/lists.texi     | 21 ++++++++++++---------
 doc/lispref/sequences.texi |  2 +-
 2 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi
index 57cefeac96..b7bb3cf6be 100644
--- a/doc/lispref/lists.texi
+++ b/doc/lispref/lists.texi
@@ -50,16 +50,19 @@ Cons Cells
 slots have similar properties).  Hence, the @sc{cdr} slot of each cons
 cell in a list refers to the following cons cell.
 
+@cindex proper list
 @cindex true list
   Also by convention, the @sc{cdr} of the last cons cell in a list is
 @code{nil}.  We call such a @code{nil}-terminated structure a
-@dfn{true list}.  In Emacs Lisp, the symbol @code{nil} is both a
-symbol and a list with no elements.  For convenience, the symbol
-@code{nil} is considered to have @code{nil} as its @sc{cdr} (and also
-as its @sc{car}).
+@dfn{proper list}@footnote{It is sometimes also referred to as a
+@dfn{true list}, but we generally do not use this terminology in this
+manual.}.  In Emacs Lisp, the symbol @code{nil} is both a symbol and a
+list with no elements.  For convenience, the symbol @code{nil} is
+considered to have @code{nil} as its @sc{cdr} (and also as its
+@sc{car}).
 
-  Hence, the @sc{cdr} of a true list is always a true list.  The
-@sc{cdr} of a nonempty true list is a true list containing all the
+  Hence, the @sc{cdr} of a proper list is always a proper list.  The
+@sc{cdr} of a nonempty proper list is a proper list containing all the
 elements except the first.
 
 @cindex dotted list
@@ -71,10 +74,10 @@ Cons Cells
 @sc{cdr} could point to one of the previous cons cells in the list.
 We call that structure a @dfn{circular list}.
 
-  For some purposes, it does not matter whether a list is true,
+  For some purposes, it does not matter whether a list is proper,
 circular or dotted.  If a program doesn't look far enough down the
 list to see the @sc{cdr} of the final cons cell, it won't care.
-However, some functions that operate on lists demand true lists and
+However, some functions that operate on lists demand proper lists and
 signal errors if given a dotted list.  Most functions that try to find
 the end of a list enter infinite loops if given a circular list.
 
@@ -538,7 +541,7 @@ Building Lists
 is itself a list, then its elements become in effect elements of the
 result list.  If the final element is not a list, the result is a
 dotted list since its final @sc{cdr} is not @code{nil} as required
-in a true list.
+in a proper list (@pxref{Cons Cells}).
 @end defun
 
   Here is an example of using @code{append}:
diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi
index 777b1cbbff..62d3305fcf 100644
--- a/doc/lispref/sequences.texi
+++ b/doc/lispref/sequences.texi
@@ -1353,7 +1353,7 @@ Vector Functions
 @defun vconcat &rest sequences
 @cindex copying vectors
 This function returns a new vector containing all the elements of
-@var{sequences}.  The arguments @var{sequences} may be true lists,
+@var{sequences}.  The arguments @var{sequences} may be proper lists,
 vectors, strings or bool-vectors.  If no @var{sequences} are given,
 the empty vector is returned.
 
-- 
2.18.0


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0003-Rearrange-definition-of-zerop-in-subr.el.patch --]
[-- Type: text/x-diff, Size: 1419 bytes --]

From a31c3a11b6661381a6a67ebd2f75043b7f3a9305 Mon Sep 17 00:00:00 2001
From: "Basil L. Contovounesios" <contovob@tcd.ie>
Date: Fri, 6 Jul 2018 00:56:45 +0300
Subject: [PATCH 3/3] ; Rearrange definition of zerop in subr.el

* lisp/subr.el (zerop): Move from under 'List functions' heading to
under 'Basic Lisp functions' heading.
---
 lisp/subr.el | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/lisp/subr.el b/lisp/subr.el
index c1d90e3fb1..10343e69db 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -359,6 +359,13 @@ apply-partially
   (lambda (&rest args2)
     (apply fun (append args args2))))
 
+(defun zerop (number)
+  "Return t if NUMBER is zero."
+  ;; Used to be in C, but it's pointless since (= 0 n) is faster anyway because
+  ;; = has a byte-code.
+  (declare (compiler-macro (lambda (_) `(= 0 ,number))))
+  (= 0 number))
+
 \f
 ;;;; List functions.
 
@@ -548,13 +555,6 @@ nbutlast
 	   (if (> n 0) (setcdr (nthcdr (- (1- m) n) list) nil))
 	   list))))
 
-(defun zerop (number)
-  "Return t if NUMBER is zero."
-  ;; Used to be in C, but it's pointless since (= 0 n) is faster anyway because
-  ;; = has a byte-code.
-  (declare (compiler-macro (lambda (_) `(= 0 ,number))))
-  (= 0 number))
-
 (defun proper-list-p (object)
   "Return OBJECT's length if it is a proper list, nil otherwise.
 A proper list is neither circular nor dotted (i.e., its last cdr
-- 
2.18.0


  parent reply	other threads:[~2018-07-09 19:25 UTC|newest]

Thread overview: 100+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-16 19:34 Predicate for true lists Basil L. Contovounesios
2018-06-04 12:12 ` Basil L. Contovounesios
2018-06-04 14:08   ` Stefan Monnier
2018-06-04 14:46     ` Basil L. Contovounesios
2018-06-04 15:31       ` Drew Adams
2018-06-04 16:14         ` Basil L. Contovounesios
2018-06-04 16:38           ` Drew Adams
2018-06-04 16:57             ` Stefan Monnier
2018-06-05  1:23   ` Paul Eggert
2018-06-05  2:57     ` Drew Adams
2018-06-05  3:08       ` Drew Adams
2018-06-05  3:12         ` Drew Adams
2018-06-05  3:25       ` Drew Adams
2018-06-05 15:05     ` Basil L. Contovounesios
2018-06-06  7:42       ` Paul Eggert
2018-06-06  9:40         ` Van L
2018-06-06 13:44           ` Stefan Monnier
2018-06-06 17:40             ` Stefan Monnier
2018-06-07  7:03             ` Van L
2018-07-05 22:31         ` Basil L. Contovounesios
2018-07-06  5:57           ` Eli Zaretskii
2018-07-06 17:16             ` Drew Adams
2018-07-06 17:38               ` Eli Zaretskii
     [not found]               ` <<83601sl0wo.fsf@gnu.org>
2018-07-06 18:00                 ` Drew Adams
2018-07-07  6:54                   ` Eli Zaretskii
     [not found]               ` <<<83601sl0wo.fsf@gnu.org>
     [not found]                 ` <<95fda70b-5893-4788-83c5-a0bb5d708304@default>
     [not found]                   ` <<8336wvleml.fsf@gnu.org>
2018-07-07 14:42                     ` Drew Adams
2018-07-06 18:04             ` Paul Eggert
2018-07-07  6:58               ` Eli Zaretskii
2018-07-07  7:20                 ` martin rudalics
2018-07-07  8:41                 ` Paul Eggert
2018-07-07 10:04                   ` Eli Zaretskii
2018-07-07 15:04                     ` Basil L. Contovounesios
2018-07-07 16:12                       ` Eli Zaretskii
2018-07-07 16:52                         ` Basil L. Contovounesios
2018-07-07 17:07                           ` Eli Zaretskii
2018-07-07 17:14                             ` Paul Eggert
2018-07-07 17:34                               ` Eli Zaretskii
2018-07-08  0:15                               ` Drew Adams
2018-07-08  4:48                                 ` Paul Eggert
2018-07-08 15:15                                   ` Drew Adams
2018-07-08 16:00                                     ` Paul Eggert
2018-07-08 17:42                                       ` Drew Adams
2018-07-08 17:47                                         ` Paul Eggert
2018-07-07 17:06                     ` Basil L. Contovounesios
2018-07-09 19:25             ` Basil L. Contovounesios [this message]
2018-07-09 19:40               ` Basil L. Contovounesios
2018-07-10  2:02                 ` Paul Eggert
2018-07-10  5:46                   ` Basil L. Contovounesios
2018-07-11  3:02                     ` Paul Eggert
2018-07-11  6:27                       ` Basil L. Contovounesios
2018-07-15 22:55                         ` Wilfred Hughes
2018-07-16  1:37                           ` Paul Eggert
2018-07-11 14:01                       ` [Emacs-diffs] master babe0d4: Rearrange definition of zerop in subr.el Karl Fogel
2018-07-11 17:12                         ` Basil L. Contovounesios
2018-07-11 17:33                           ` Paul Eggert
2018-07-12 15:34                             ` Basil L. Contovounesios
2018-07-12 15:43                               ` Basil L. Contovounesios
2019-04-09 12:51                       ` Predicate for true lists Basil L. Contovounesios
2019-04-09 15:33                         ` Stefan Monnier
2019-04-09 16:20                           ` Basil L. Contovounesios
2019-04-09 16:32                             ` Stefan Monnier
2019-04-09 16:54                               ` Daniel Colascione
2019-04-09 17:27                                 ` Basil L. Contovounesios
2019-04-09 17:27                               ` Basil L. Contovounesios
2019-04-09 20:08                               ` Unused value of error-free function warning (was: Predicate for true lists) Basil L. Contovounesios
2019-04-09 20:40                                 ` Unused value of error-free function warning Stefan Monnier
2019-04-09 20:12                           ` Predicate for true lists Basil L. Contovounesios
2019-04-09 20:41                             ` Stefan Monnier
2019-04-10  2:32                             ` Eli Zaretskii
2019-04-10 14:16                               ` Alex Branham
2019-04-10 14:34                                 ` Basil L. Contovounesios
2019-04-10 15:01                                   ` Drew Adams
2019-04-10 15:45                                     ` Basil L. Contovounesios
2019-04-10 16:04                                       ` Eli Zaretskii
2019-04-17 17:56                                       ` Basil L. Contovounesios
2019-04-17 18:11                                         ` Stefan Monnier
2019-04-21 21:42                                           ` Basil L. Contovounesios
2019-04-17 18:55                                         ` Drew Adams
2019-04-21 21:24                                           ` Basil L. Contovounesios
2019-04-22  0:03                                             ` Drew Adams
2019-04-22  1:12                                               ` Michael Heerdegen
2019-04-22  9:39                                                 ` Drew Adams
2019-04-18 14:37                                         ` Eli Zaretskii
2019-04-21 18:30                                           ` Basil L. Contovounesios
2019-04-21 19:39                                             ` Eli Zaretskii
2019-04-21 21:37                                               ` Basil L. Contovounesios
2019-04-22  0:06                                                 ` Drew Adams
2019-04-22  7:49                                                 ` Eli Zaretskii
2019-04-22 12:59                                                   ` Basil L. Contovounesios
2019-04-22 13:12                                                     ` Eli Zaretskii
2019-04-22 15:19                                                       ` Basil L. Contovounesios
2019-04-21 19:41                                             ` Eli Zaretskii
2019-04-21 21:41                                               ` Basil L. Contovounesios
2019-04-22  6:39                                                 ` Eli Zaretskii
2019-04-22 12:58                                                   ` Basil L. Contovounesios
2018-07-06 17:00           ` Drew Adams
2018-07-06 17:20             ` Paul Eggert
2018-07-06 17:33             ` Eli Zaretskii
2018-07-08 22:38             ` Basil L. Contovounesios
2018-07-06 17:30           ` Paul Eggert
     [not found] <<87fu3vdjjk.fsf@tcd.ie>
     [not found] <<<87fu3vdjjk.fsf@tcd.ie>

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

  List information: https://www.gnu.org/software/emacs/

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

  git send-email \
    --in-reply-to=87sh4s9poo.fsf@tcd.ie \
    --to=contovob@tcd.ie \
    --cc=eggert@cs.ucla.edu \
    --cc=eliz@gnu.org \
    --cc=emacs-devel@gnu.org \
    /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 public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).