diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi index fc52f11cf4a..ee43389399a 100644 --- a/doc/lispref/numbers.texi +++ b/doc/lispref/numbers.texi @@ -409,6 +409,16 @@ if so, @code{nil} otherwise. The argument must be a number. @code{(zerop x)} is equivalent to @code{(= x 0)}. @end defun +@defun oddp integer +This predicate tests whether its argument is an odd number, and returns +@code{t} if so, @code{nil} otherwise. The argument must be an integer. +@end defun + +@defun evenp integer +This predicate tests whether its argument is an even number, and returns +@code{t} if so, @code{nil} otherwise. The argument must be an integer. +@end defun + @node Comparison of Numbers @section Comparison of Numbers @cindex number comparison diff --git a/doc/misc/cl.texi b/doc/misc/cl.texi index fbed1265aa3..f481f6f2721 100644 --- a/doc/misc/cl.texi +++ b/doc/misc/cl.texi @@ -2450,7 +2450,7 @@ by the name @code{it} in the ``then'' part. For example: (setq funny-numbers '(6 13 -1)) @result{} (6 13 -1) (cl-loop for x below 10 - if (cl-oddp x) + if (oddp x) collect x into odds and if (memq x funny-numbers) return (cdr it) end else @@ -3055,7 +3055,7 @@ This section defines a few simple Common Lisp operations on numbers that were left out of Emacs Lisp. @menu -* Predicates on Numbers:: @code{cl-plusp}, @code{cl-oddp}, etc. +* Predicates on Numbers:: @code{cl-plusp}, @code{cl-minusp}, etc. * Numerical Functions:: @code{cl-floor}, @code{cl-ceiling}, etc. * Random Numbers:: @code{cl-random}, @code{cl-make-random-state}. * Implementation Parameters:: @code{cl-most-positive-float}, etc. @@ -3078,16 +3078,6 @@ This predicate tests whether @var{number} is negative. It is an error if the argument is not a number. @end defun -@defun cl-oddp integer -This predicate tests whether @var{integer} is odd. It is an -error if the argument is not an integer. -@end defun - -@defun cl-evenp integer -This predicate tests whether @var{integer} is even. It is an -error if the argument is not an integer. -@end defun - @defun cl-digit-char-p char radix Test if @var{char} is a digit in the specified @var{radix} (default is 10). If it is, return the numerical value of digit @var{char} in diff --git a/etc/NEWS b/etc/NEWS index 6d934b2029c..a0d0f8b9818 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1265,6 +1265,12 @@ restore the old behavior, you can set 'eshell-pwd-convert-function' to * Lisp Changes in Emacs 31.1 ++++ +** New functions 'oddp' and 'evenp'. +They return non-nil if an integer is odd or even, respectively, and +signal an error if they are given a non-integer. The 'cl-lib' functions +'cl-oddp' and 'cl-evenp' are now aliases for 'oddp' and 'evenp'. + ** Time & Date +++ diff --git a/lisp/emacs-lisp/cl-lib.el b/lisp/emacs-lisp/cl-lib.el index dba01b28325..1fc36517796 100644 --- a/lisp/emacs-lisp/cl-lib.el +++ b/lisp/emacs-lisp/cl-lib.el @@ -280,17 +280,17 @@ so that they are registered at compile-time as well as run-time." (declare (side-effect-free t)) (< number 0)) -(defun cl-oddp (integer) - "Return t if INTEGER is odd." - (declare (side-effect-free t) - (compiler-macro (lambda (_) `(eq (logand ,integer 1) 1)))) - (eq (logand integer 1) 1)) +(defalias 'cl-oddp #'oddp + "Return t if INTEGER is odd. -(defun cl-evenp (integer) - "Return t if INTEGER is even." - (declare (side-effect-free t) - (compiler-macro (lambda (_) `(eq (logand ,integer 1) 0)))) - (eq (logand integer 1) 0)) +This function is considered deprecated in favor of the built-in function +`evenp' that was added in Emacs 31.1.") + +(defalias 'cl-evenp #'evenp + "Return t if INTEGER is even. + +This function is considered deprecated in favor of the built-in function +`evenp' that was added in Emacs 31.1.") (defconst cl-digit-char-table (let* ((digits (make-vector 256 nil)) diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index cc9971b232f..af995123dc5 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el @@ -278,17 +278,17 @@ A FUNC form can have any number of `:no-eval' (or `:no-value'), :args (function map) :eval (map-values-apply #'1+ (list '(1 . 2) '(3 . 4)))) (map-filter - :eval (map-filter (lambda (k _) (cl-oddp k)) (list '(1 . 2) '(4 . 6))) - :eval (map-filter (lambda (k v) (cl-evenp (+ k v))) (list '(1 . 2) '(4 . 6)))) + :eval (map-filter (lambda (k _) (oddp k)) (list '(1 . 2) '(4 . 6))) + :eval (map-filter (lambda (k v) (evenp (+ k v))) (list '(1 . 2) '(4 . 6)))) (map-remove - :eval (map-remove (lambda (k _) (cl-oddp k)) (list '(1 . 2) '(4 . 6))) - :eval (map-remove (lambda (k v) (cl-evenp (+ k v))) (list '(1 . 2) '(4 . 6)))) + :eval (map-remove (lambda (k _) (oddp k)) (list '(1 . 2) '(4 . 6))) + :eval (map-remove (lambda (k v) (evenp (+ k v))) (list '(1 . 2) '(4 . 6)))) (map-some - :eval (map-some (lambda (k _) (cl-oddp k)) (list '(1 . 2) '(4 . 6))) - :eval (map-some (lambda (k v) (cl-evenp (+ k v))) (list '(1 . 2) '(4 . 6)))) + :eval (map-some (lambda (k _) (oddp k)) (list '(1 . 2) '(4 . 6))) + :eval (map-some (lambda (k v) (evenp (+ k v))) (list '(1 . 2) '(4 . 6)))) (map-every-p - :eval (map-every-p (lambda (k _) (cl-oddp k)) (list '(1 . 2) '(4 . 6))) - :eval (map-every-p (lambda (k v) (cl-evenp (+ k v))) (list '(1 . 3) '(4 . 6)))) + :eval (map-every-p (lambda (k _) (oddp k)) (list '(1 . 2) '(4 . 6))) + :eval (map-every-p (lambda (k v) (evenp (+ k v))) (list '(1 . 3) '(4 . 6)))) "Combining and changing maps" (map-merge :eval (map-merge 'alist '(1 2 3 4) #s(hash-table data (5 6 7 8))) @@ -1418,10 +1418,10 @@ A FUNC form can have any number of `:no-eval' (or `:no-value'), (cl-minusp :eval (cl-minusp 0) :eval (cl-minusp -1)) - (cl-oddp - :eval (cl-oddp 3)) - (cl-evenp - :eval (cl-evenp 6)) + (oddp + :eval (oddp 3)) + (evenp + :eval (evenp 6)) (bignump :eval (bignump 4) :eval (bignump (expt 2 90))) diff --git a/lisp/obsolete/cl.el b/lisp/obsolete/cl.el index 2ee7e70e4ea..4fb49b596e2 100644 --- a/lisp/obsolete/cl.el +++ b/lisp/obsolete/cl.el @@ -272,8 +272,6 @@ first svref copy-seq - evenp - oddp minusp plusp floatp-safe diff --git a/lisp/subr.el b/lisp/subr.el index 77e909d1bf6..173c69675aa 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -550,6 +550,20 @@ was called." (compiler-macro (lambda (_) `(= 0 ,number)))) (= 0 number)) +(defun oddp (integer) + "Return t if INTEGER is odd." + (declare (ftype (function (integer) boolean)) + (side-effect-free t) + (compiler-macro (lambda (_) `(eq (logand ,integer 1) 1)))) + (eq (logand integer 1) 1)) + +(defun evenp (integer) + "Return t if INTEGER is even." + (declare (ftype (function (integer) boolean)) + (side-effect-free t) + (compiler-macro (lambda (_) `(eq (logand ,integer 1) 0)))) + (eq (logand integer 1) 0)) + (defun fixnump (object) "Return t if OBJECT is a fixnum." (declare (ftype (function (t) boolean)) diff --git a/test/lisp/emacs-lisp/cl-lib-tests.el b/test/lisp/emacs-lisp/cl-lib-tests.el index 12de268bced..4121c1bfdb0 100644 --- a/test/lisp/emacs-lisp/cl-lib-tests.el +++ b/test/lisp/emacs-lisp/cl-lib-tests.el @@ -111,26 +111,6 @@ (should-not (cl-minusp 1.0e+INF)) (should-error (cl-minusp "-42") :type 'wrong-type-argument)) -(ert-deftest cl-lib-test-oddp () - (should (cl-oddp -3)) - (should (cl-oddp 3)) - (should-not (cl-oddp -2)) - (should-not (cl-oddp 0)) - (should-not (cl-oddp 2)) - (should-error (cl-oddp 3.0e+NaN) :type 'wrong-type-argument) - (should-error (cl-oddp 3.0) :type 'wrong-type-argument) - (should-error (cl-oddp "3") :type 'wrong-type-argument)) - -(ert-deftest cl-lib-test-evenp () - (should (cl-evenp -2)) - (should (cl-evenp 0)) - (should (cl-evenp 2)) - (should-not (cl-evenp -3)) - (should-not (cl-evenp 3)) - (should-error (cl-evenp 2.0e+NaN) :type 'wrong-type-argument) - (should-error (cl-evenp 2.0) :type 'wrong-type-argument) - (should-error (cl-evenp "2") :type 'wrong-type-argument)) - (ert-deftest cl-digit-char-p () (should (eql 3 (cl-digit-char-p ?3))) (should (eql 10 (cl-digit-char-p ?a 11))) diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el index 29767ed07b5..1b209ab6383 100644 --- a/test/lisp/subr-tests.el +++ b/test/lisp/subr-tests.el @@ -45,6 +45,26 @@ (should-not (zerop (1- most-negative-fixnum))) (should-error (zerop "-5") :type 'wrong-type-argument)) +(ert-deftest subr-test-oddp () + (should (oddp -3)) + (should (oddp 3)) + (should-not (oddp -2)) + (should-not (oddp 0)) + (should-not (oddp 2)) + (should-error (oddp 3.0e+NaN) :type 'wrong-type-argument) + (should-error (oddp 3.0) :type 'wrong-type-argument) + (should-error (oddp "3") :type 'wrong-type-argument)) + +(ert-deftest subr-test-evenp () + (should (evenp -2)) + (should (evenp 0)) + (should (evenp 2)) + (should-not (evenp -3)) + (should-not (evenp 3)) + (should-error (evenp 2.0e+NaN) :type 'wrong-type-argument) + (should-error (evenp 2.0) :type 'wrong-type-argument) + (should-error (evenp "2") :type 'wrong-type-argument)) + (ert-deftest let-when-compile () ;; good case (should (equal (macroexpand '(let-when-compile ((foo (+ 2 3)))