From 16ba96ad3ddbd5607a2e40ffe5abfe53c3e6a1c5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mattias=20Engdeg=C3=A5rd?= Date: Wed, 15 Feb 2023 12:01:25 +0100 Subject: [PATCH] Add some `pure` and `side-effect-free` declarations * lisp/subr.el (string-to-list, string-to-vector, string-or-null-p) (booleanp, special-form-p, plistp, macrop, compiled-function-p) (flatten-tree): * lisp/emacs-lisp/subr-x.el (string-join, string-truncate-left) (string-blank-p, string-remove-prefix, string-remove-suffix) (string-pad, string-chop-newline): Declare functions pure, side-effect-free, and/or error-free. --- lisp/emacs-lisp/subr-x.el | 7 +++++++ lisp/subr.el | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 8cdbdf1ef6a..947390b3de3 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -102,6 +102,7 @@ threading." "Join all STRINGS using SEPARATOR. Optional argument SEPARATOR must be a string, a vector, or a list of characters; nil stands for the empty string." + (declare (pure t) (side-effect-free t)) (mapconcat #'identity strings separator)) (define-obsolete-function-alias 'string-reverse 'reverse "25.1") @@ -112,6 +113,7 @@ characters; nil stands for the empty string." When truncating, \"...\" is always prepended to the string, so the resulting string may be longer than the original if LENGTH is 3 or smaller." + (declare (pure t) (side-effect-free t)) (let ((strlen (length string))) (if (<= strlen length) string @@ -124,16 +126,19 @@ the resulting string may be longer than the original if LENGTH is "Check whether STRING is either empty or only whitespace. The following characters count as whitespace here: space, tab, newline and carriage return." + (declare (pure t) (side-effect-free t)) (string-match-p "\\`[ \t\n\r]*\\'" string)) (defsubst string-remove-prefix (prefix string) "Remove PREFIX from STRING if present." + (declare (pure t) (side-effect-free t)) (if (string-prefix-p prefix string) (substring string (length prefix)) string)) (defsubst string-remove-suffix (suffix string) "Remove SUFFIX from STRING if present." + (declare (pure t) (side-effect-free t)) (if (string-suffix-p suffix string) (substring string 0 (- (length string) (length suffix))) string)) @@ -252,6 +257,7 @@ is done. If START is nil (or not present), the padding is done to the end of the string, and if non-nil, padding is done to the start of the string." + (declare (pure t) (side-effect-free t)) (unless (natnump length) (signal 'wrong-type-argument (list 'natnump length))) (let ((pad-length (- length (length string)))) @@ -261,6 +267,7 @@ the string." (defun string-chop-newline (string) "Remove the final newline (if any) from STRING." + (declare (pure t) (side-effect-free t)) (string-remove-suffix "\n" string)) (defun replace-region-contents (beg end replace-fn diff --git a/lisp/subr.el b/lisp/subr.el index 898ecb6e358..a5fc566cc74 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -4124,15 +4124,18 @@ system's shell." (defsubst string-to-list (string) "Return a list of characters in STRING." + (declare (side-effect-free t)) (append string nil)) (defsubst string-to-vector (string) "Return a vector of characters in STRING." + (declare (side-effect-free t)) (vconcat string)) (defun string-or-null-p (object) "Return t if OBJECT is a string or nil. Otherwise, return nil." + (declare (pure t) (side-effect-free error-free)) (or (stringp object) (null object))) (defun list-of-strings-p (object) @@ -4145,21 +4148,25 @@ Otherwise, return nil." (defun booleanp (object) "Return t if OBJECT is one of the two canonical boolean values: t or nil. Otherwise, return nil." + (declare (pure t) (side-effect-free error-free)) (and (memq object '(nil t)) t)) (defun special-form-p (object) "Non-nil if and only if OBJECT is a special form." + (declare (side-effect-free error-free)) (if (and (symbolp object) (fboundp object)) (setq object (indirect-function object))) (and (subrp object) (eq (cdr (subr-arity object)) 'unevalled))) (defun plistp (object) "Non-nil if and only if OBJECT is a valid plist." + (declare (pure t) (side-effect-free error-free)) (let ((len (proper-list-p object))) (and len (zerop (% len 2))))) (defun macrop (object) "Non-nil if and only if OBJECT is a macro." + (declare (side-effect-free t)) (let ((def (indirect-function object))) (when (consp def) (or (eq 'macro (car def)) @@ -4169,6 +4176,7 @@ Otherwise, return nil." "Return non-nil if OBJECT is a function that has been compiled. Does not distinguish between functions implemented in machine code or byte-code." + (declare (side-effect-free error-free)) (or (subrp object) (byte-code-function-p object))) (defun field-at-pos (pos) @@ -6843,6 +6851,7 @@ returned list are in the same order as in TREE. \(flatten-tree \\='(1 (2 . 3) nil (4 5 (6)) 7)) => (1 2 3 4 5 6 7)" + (declare (side-effect-free error-free)) (let (elems) (while (consp tree) (let ((elem (pop tree))) -- 2.39.2