]> git.eshelyaron.com Git - emacs.git/commitdiff
Inline side-effect-free declarations in cl-lib.el
authorStefan Kangas <stefankangas@gmail.com>
Thu, 13 Feb 2025 03:24:05 +0000 (04:24 +0100)
committerEshel Yaron <me@eshelyaron.com>
Fri, 14 Feb 2025 11:44:01 +0000 (12:44 +0100)
* lisp/emacs-lisp/cl-macs.el: Move side-effect-free declarations from
here...
* lisp/emacs-lisp/cl-extra.el (cl-gcd, cl-lcm, cl-isqrt, cl-floor)
(cl-ceiling, cl-truncate, cl-round, cl-mod, cl-rem, cl-signum)
(cl-subseq, cl-list-length, cl-get, cl-getf):
* lisp/emacs-lisp/cl-lib.el (cl-plusp, cl-minusp, cl-oddp, cl-evenp)
(cl-fifth, cl-sixth, cl-seventh, cl-eighth, cl-ninth, cl-tenth)
(cl-ldiff, cl-pairlis):
* lisp/emacs-lisp/cl-seq.el (cl-endp): ...to have them inline here.

* lisp/emacs-lisp/cl-macs.el: Move side-effect-and-error-free
declarations from here...
* lisp/emacs-lisp/cl-extra.el (cl-equalp, cl-random-state-p):
* lisp/emacs-lisp/cl-lib.el (cl-list*, cl-acons): ...to have them inline
here.  (Bug#76247)

(cherry picked from commit 7d9e67be13f72b7c7c8815f651c8fa5f74a79c54)

lisp/emacs-lisp/cl-extra.el
lisp/emacs-lisp/cl-lib.el
lisp/emacs-lisp/cl-macs.el
lisp/emacs-lisp/cl-seq.el

index fb5d04df329968c3e19fee76e4243ef0f4b36611..5dc6bea5148f1c25338e4bccc05c8aa19db534ce 100644 (file)
@@ -69,6 +69,7 @@ TYPE is a Common Lisp type specifier.
 This is like `equal', except that it accepts numerically equal
 numbers of different types (float vs. integer), and also compares
 strings case-insensitively."
+  (declare (side-effect-free error-free))
   (cond ((eq x y) t)
        ((stringp x)
         (and (stringp y) (string-equal-ignore-case x y)))
@@ -317,6 +318,7 @@ non-nil value.
 ;;;###autoload
 (defun cl-gcd (&rest args)
   "Return the greatest common divisor of the arguments."
+  (declare (side-effect-free t))
   (let ((a (or (pop args) 0)))
     (dolist (b args)
       (while (/= b 0)
@@ -326,6 +328,7 @@ non-nil value.
 ;;;###autoload
 (defun cl-lcm (&rest args)
   "Return the least common multiple of the arguments."
+  (declare (side-effect-free t))
   (if (memq 0 args)
       0
     (let ((a (or (pop args) 1)))
@@ -336,6 +339,7 @@ non-nil value.
 ;;;###autoload
 (defun cl-isqrt (x)
   "Return the integer square root of the (integer) argument X."
+  (declare (side-effect-free t))
   (if (and (integerp x) (> x 0))
       (let ((g (ash 2 (/ (logb x) 2)))
            g2)
@@ -348,6 +352,7 @@ non-nil value.
 (defun cl-floor (x &optional y)
   "Return a list of the floor of X and the fractional part of X.
 With two arguments, return floor and remainder of their quotient."
+  (declare (side-effect-free t))
   (let ((q (floor x y)))
     (list q (- x (if y (* y q) q)))))
 
@@ -355,6 +360,7 @@ With two arguments, return floor and remainder of their quotient."
 (defun cl-ceiling (x &optional y)
   "Return a list of the ceiling of X and the fractional part of X.
 With two arguments, return ceiling and remainder of their quotient."
+  (declare (side-effect-free t))
   (let ((res (cl-floor x y)))
     (if (= (car (cdr res)) 0) res
       (list (1+ (car res)) (- (car (cdr res)) (or y 1))))))
@@ -363,6 +369,7 @@ With two arguments, return ceiling and remainder of their quotient."
 (defun cl-truncate (x &optional y)
   "Return a list of the integer part of X and the fractional part of X.
 With two arguments, return truncation and remainder of their quotient."
+  (declare (side-effect-free t))
   (if (eq (>= x 0) (or (null y) (>= y 0)))
       (cl-floor x y) (cl-ceiling x y)))
 
@@ -370,6 +377,7 @@ With two arguments, return truncation and remainder of their quotient."
 (defun cl-round (x &optional y)
   "Return a list of X rounded to the nearest integer and the remainder.
 With two arguments, return rounding and remainder of their quotient."
+  (declare (side-effect-free t))
   (if y
       (if (and (integerp x) (integerp y))
          (let* ((hy (/ y 2))
@@ -388,16 +396,19 @@ With two arguments, return rounding and remainder of their quotient."
 ;;;###autoload
 (defun cl-mod (x y)
   "The remainder of X divided by Y, with the same sign as Y."
+  (declare (side-effect-free t))
   (nth 1 (cl-floor x y)))
 
 ;;;###autoload
 (defun cl-rem (x y)
   "The remainder of X divided by Y, with the same sign as X."
+  (declare (side-effect-free t))
   (nth 1 (cl-truncate x y)))
 
 ;;;###autoload
 (defun cl-signum (x)
   "Return 1 if X is positive, -1 if negative, 0 if zero."
+  (declare (side-effect-free t))
   (cond ((> x 0) 1) ((< x 0) -1) (t 0)))
 
 ;;;###autoload
@@ -441,12 +452,13 @@ as an integer unless JUNK-ALLOWED is non-nil."
 ;; Random numbers.
 
 (defun cl--random-time ()
-    "Return high-precision timestamp from `time-convert'.
+  "Return high-precision timestamp from `time-convert'.
 
 For example, suitable for use as seed by `cl-make-random-state'."
-    (car (time-convert nil t)))
+  (car (time-convert nil t)))
 
 ;;;###autoload (autoload 'cl-random-state-p "cl-extra")
+;;;###autoload (function-put 'cl-random-state-p 'side-effect-free 'error-free)
 (cl-defstruct (cl--random-state
                (:copier nil)
                (:predicate cl-random-state-p)
@@ -549,6 +561,7 @@ If END is omitted, it defaults to the length of the sequence.
 If START or END is negative, it counts from the end.
 Signal an error if START or END are outside of the sequence (i.e
 too large if positive or too small if negative)."
+  (declare (side-effect-free t))
   (declare (gv-setter
             (lambda (new)
               (macroexp-let2 nil new new
@@ -581,6 +594,7 @@ too large if positive or too small if negative)."
 ;;;###autoload
 (defun cl-list-length (x)
   "Return the length of list X.  Return nil if list is circular."
+  (declare (side-effect-free t))
   (cl-check-type x list)
   (condition-case nil
       (length x)
@@ -599,7 +613,8 @@ too large if positive or too small if negative)."
 (defun cl-get (sym tag &optional def)
   "Return the value of SYMBOL's PROPNAME property, or DEFAULT if none.
 \n(fn SYMBOL PROPNAME &optional DEFAULT)"
-  (declare (compiler-macro cl--compiler-macro-get)
+  (declare (side-effect-free t)
+           (compiler-macro cl--compiler-macro-get)
            (gv-setter (lambda (store) (ignore def) `(put ,sym ,tag ,store))))
   (cl-getf (symbol-plist sym) tag def))
 (autoload 'cl--compiler-macro-get "cl-macs")
@@ -609,7 +624,8 @@ too large if positive or too small if negative)."
   "Search PROPLIST for property PROPNAME; return its value or DEFAULT.
 PROPLIST is a list of the sort returned by `symbol-plist'.
 \n(fn PROPLIST PROPNAME &optional DEFAULT)"
-  (declare (gv-expander
+  (declare (side-effect-free t)
+           (gv-expander
             (lambda (do)
               (gv-letplace (getter setter) plist
                 (macroexp-let2* nil ((k tag) (d def))
index 918e452f2d6aa40ceb4592b5fdea6d4b6c11c618..8635042aaf158b32577ef3dc509d0634c6dde413 100644 (file)
@@ -272,10 +272,12 @@ so that they are registered at compile-time as well as run-time."
 
 (defsubst cl-plusp (number)
   "Return t if NUMBER is positive."
+  (declare (side-effect-free t))
   (> number 0))
 
 (defsubst cl-minusp (number)
   "Return t if NUMBER is negative."
+  (declare (side-effect-free t))
   (< number 0))
 
 (defalias 'cl-oddp 'oddp)
@@ -381,32 +383,38 @@ SEQ, this is like `mapcar'.  With several, it is like the Common Lisp
 
 (defsubst cl-fifth (x)
   "Return the fifth element of the list X."
-  (declare (gv-setter (lambda (store) `(setcar (nthcdr 4 ,x) ,store))))
+  (declare (side-effect-free t)
+           (gv-setter (lambda (store) `(setcar (nthcdr 4 ,x) ,store))))
   (nth 4 x))
 
 (defsubst cl-sixth (x)
   "Return the sixth element of the list X."
-  (declare (gv-setter (lambda (store) `(setcar (nthcdr 5 ,x) ,store))))
+  (declare (side-effect-free t)
+           (gv-setter (lambda (store) `(setcar (nthcdr 5 ,x) ,store))))
   (nth 5 x))
 
 (defsubst cl-seventh (x)
   "Return the seventh element of the list X."
-  (declare (gv-setter (lambda (store) `(setcar (nthcdr 6 ,x) ,store))))
+  (declare (side-effect-free t)
+           (gv-setter (lambda (store) `(setcar (nthcdr 6 ,x) ,store))))
   (nth 6 x))
 
 (defsubst cl-eighth (x)
   "Return the eighth element of the list X."
-  (declare (gv-setter (lambda (store) `(setcar (nthcdr 7 ,x) ,store))))
+  (declare (side-effect-free t)
+           (gv-setter (lambda (store) `(setcar (nthcdr 7 ,x) ,store))))
   (nth 7 x))
 
 (defsubst cl-ninth (x)
   "Return the ninth element of the list X."
-  (declare (gv-setter (lambda (store) `(setcar (nthcdr 8 ,x) ,store))))
+  (declare (side-effect-free t)
+           (gv-setter (lambda (store) `(setcar (nthcdr 8 ,x) ,store))))
   (nth 8 x))
 
 (defsubst cl-tenth (x)
   "Return the tenth element of the list X."
-  (declare (gv-setter (lambda (store) `(setcar (nthcdr 9 ,x) ,store))))
+  (declare (side-effect-free t)
+           (gv-setter (lambda (store) `(setcar (nthcdr 9 ,x) ,store))))
   (nth 9 x))
 
 (defalias 'cl-caaar #'caaar)
@@ -450,7 +458,8 @@ SEQ, this is like `mapcar'.  With several, it is like the Common Lisp
 Thus, `(cl-list* A B C D)' is equivalent to `(nconc (list A B C) D)', or to
 `(cons A (cons B (cons C D)))'.
 \n(fn ARG...)"
-  (declare (compiler-macro cl--compiler-macro-list*))
+  (declare (side-effect-free error-free)
+           (compiler-macro cl--compiler-macro-list*))
   (cond ((not rest) arg)
        ((not (cdr rest)) (cons arg (car rest)))
        (t (let* ((n (length rest))
@@ -461,6 +470,7 @@ Thus, `(cl-list* A B C D)' is equivalent to `(nconc (list A B C) D)', or to
 
 (defun cl-ldiff (list sublist)
   "Return a copy of LIST with the tail SUBLIST removed."
+  (declare (side-effect-free t))
   (let ((res nil))
     (while (and (consp list) (not (eq list sublist)))
       (push (pop list) res))
@@ -517,6 +527,7 @@ Return a copy of TREE with all elements `eql' to OLD replaced by NEW.
 (defun cl-acons (key value alist)
   "Add KEY and VALUE to ALIST.
 Return a new list with (cons KEY VALUE) as car and ALIST as cdr."
+  (declare (side-effect-free error-free))
   (cons (cons key value) alist))
 
 (defun cl-pairlis (keys values &optional alist)
@@ -524,6 +535,7 @@ Return a new list with (cons KEY VALUE) as car and ALIST as cdr."
 Return a new alist composed by associating KEYS to corresponding VALUES;
 the process stops as soon as KEYS or VALUES run out.
 If ALIST is non-nil, the new pairs are prepended to it."
+  (declare (side-effect-free t))
   (nconc (cl-mapcar 'cons keys values) alist))
 
 ;;; Miscellaneous.
index 7185b20d65105fc0b3f8dd5b2c4d21672ec7e913..80c13d84b70c155557481506a503259ac022de71 100644 (file)
@@ -3729,20 +3729,6 @@ macro that returns its `&whole' argument."
 (cl-proclaim '(inline cl-acons cl-map cl-notany cl-notevery cl-revappend
                cl-nreconc))
 
-;;; Things that are side-effect-free.
-(mapc (lambda (x) (function-put x 'side-effect-free t))
-      '(cl-first cl-second cl-third cl-fourth
-        cl-fifth cl-sixth cl-seventh
-        cl-eighth cl-ninth cl-tenth
-        cl-rest cl-endp cl-plusp cl-minusp
-        cl-oddp cl-evenp cl-signum cl-ldiff cl-pairlis cl-gcd
-        cl-lcm cl-isqrt cl-floor cl-ceiling cl-truncate cl-round cl-mod cl-rem
-        cl-subseq cl-list-length cl-get cl-getf))
-
-;;; Things that are side-effect-and-error-free.
-(mapc (lambda (x) (function-put x 'side-effect-free 'error-free))
-      '(cl-list* cl-acons cl-equalp
-        cl-random-state-p copy-tree))
 
 ;;; Things whose return value should probably be used.
 (mapc (lambda (x) (function-put x 'important-return-value t))
index 7a79488f1f59048ba5fd6e2ce2e513b7fbfdc4af..1878153f8112e54c3c59c00bb2d29cdb0a395606 100644 (file)
 (defun cl-endp (x)
   "Return true if X is the empty list; false if it is a cons.
 Signal an error if X is not a list."
+  (declare (side-effect-free t))
   (cl-check-type x list)
   (null x))