diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi index 90d0bfc4d12..b361134be59 100644 --- a/doc/lispref/lists.texi +++ b/doc/lispref/lists.texi @@ -428,20 +428,26 @@ This function returns @code{t} if @var{pred} is true for all elements in @end example @end defun -@defun any pred list +@defun member-if pred list This function returns non-@code{nil} if @var{pred} is true for at least one element in @var{list}. The returned value is the longest @var{list} suffix whose first element satisfies @var{pred}. @example @group -(any #'symbolp '(1 2 3 4)) @result{} nil -(any #'symbolp '(1 2 a b 3 4)) @result{} (a b 3 4) -(any #'symbolp '()) @result{} nil +(member-if #'symbolp '(1 2 3 4)) @result{} nil +(member-if #'symbolp '(1 2 a b 3 4)) @result{} (a b 3 4) +(member-if #'symbolp '()) @result{} nil @end group @end example @end defun +@defun any pred list +This function is an alias for @code{member-if}. It may be preferable in +contexts which do not make use of the returned value, but only whether +or not it was nil. +@end defun + @defun last list &optional n This function returns the last link of @var{list}. The @code{car} of this link is the list's last element. If @var{list} is null, diff --git a/doc/misc/cl.texi b/doc/misc/cl.texi index bf980c0888f..86af253bdf1 100644 --- a/doc/misc/cl.texi +++ b/doc/misc/cl.texi @@ -3825,10 +3825,11 @@ comparisons; it is equivalent to @code{(cl-member @var{item} @var{list} :test 'equal)}. @end defun -@findex cl-member-if @findex cl-member-if-not -The @code{cl-member-if} and @code{cl-member-if-not} functions -analogously search for elements that satisfy a given predicate. +The @code{cl-member-if-not} function analogously searches for elements +that don't satisfy a given predicate. This is deprecated in the Common +Lisp standard; prefer the core function @code{member-if} with a negated +predicate function. @defun cl-tailp sublist list This function returns @code{t} if @var{sublist} is a sublist of diff --git a/etc/NEWS b/etc/NEWS index 0e0f8743ed3..57a1ee5dcf0 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1686,15 +1686,16 @@ the list of types to which a value belongs. These functions or macros have been added to Emacs Lisp, and the old names are now aliases for the built-in equivalents: -- 'cl-incf' renamed to 'incf' -- 'cl-decf' renamed to 'decf' -- 'cl-oddp' renamed to 'oddp' -- 'cl-evenp' renamed to 'evenp' -- 'cl-plusp' renamed to 'plusp' -- 'cl-minusp' renamed to 'minusp' +- 'cl-incf' renamed to 'incf' +- 'cl-decf' renamed to 'decf' +- 'cl-oddp' renamed to 'oddp' +- 'cl-evenp' renamed to 'evenp' +- 'cl-plusp' renamed to 'plusp' +- 'cl-minusp' renamed to 'minusp' +- 'cl-member-if' renamed to 'member-if' -The old names are considered deprecated, and will be marked as obsolete -in some future release. +The old names are deprecated, and will be marked as obsolete in some +future release. +++ *** 'cl-labels' now also accepts '(FUNC EXP)' bindings, like 'cl-flet'. @@ -4060,8 +4061,8 @@ signal an error if they are given a non-integer. These work like 'drop' and 'take' but use a predicate instead of counting. +++ -** New functions 'any' and 'all'. -These return non-nil for lists where any and all elements, respectively, +** New function 'all' and function alias 'any'. +These return non-nil for lists where all and any elements, respectively, satisfy a given predicate. +++ diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 35594bb4dab..e2d73804eb5 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -3644,7 +3644,7 @@ This assumes the function has the `important-return-value' property." cl-search )) (put f 'funarg-positions '(:test :test-not :key))) -(dolist (f '( cl-find-if cl-find-if-not cl-member-if cl-member-if-not +(dolist (f '( cl-find-if cl-find-if-not member-if cl-member-if-not cl-assoc-if cl-assoc-if-not cl-rassoc-if cl-rassoc-if-not cl-position-if cl-position-if-not cl-count-if cl-count-if-not cl-remove-if cl-remove-if-not cl-delete-if cl-delete-if-not diff --git a/lisp/emacs-lisp/cl-lib.el b/lisp/emacs-lisp/cl-lib.el index 8174050cc0c..6b7b8ca3e54 100644 --- a/lisp/emacs-lisp/cl-lib.el +++ b/lisp/emacs-lisp/cl-lib.el @@ -113,8 +113,8 @@ The return value is the incremented value of PLACE. If X is specified, it should be an expression that should evaluate to a number. -This macro is considered deprecated in favor of the built-in macro -`incf' that was added in Emacs 31.1.") +This macro is deprecated in favor of the built-in macro `incf' that was +added in Emacs 31.1.") (defalias 'cl-decf #'decf "Decrement PLACE by X (1 by default). @@ -124,8 +124,8 @@ The return value is the decremented value of PLACE. If X is specified, it should be an expression that should evaluate to a number. -This macro is considered deprecated in favor of the built-in macro -`decf' that was added in Emacs 31.1.") +This macro is deprecated in favor of the built-in macro `decf' that was +added in Emacs 31.1.") (defmacro cl-pushnew (x place &rest keys) "Add X to the list stored in PLACE unless X is already in the list. @@ -269,26 +269,26 @@ so that they are registered at compile-time as well as run-time." (defalias 'cl-plusp #'plusp "Return t if NUMBER is positive. -This function is considered deprecated in favor of the built-in function -`plusp' that was added in Emacs 31.1.") +This function is deprecated in favor of the built-in function `plusp' +that was added in Emacs 31.1.") (defalias 'cl-minusp #'minusp "Return t if NUMBER is negative. -This function is considered deprecated in favor of the built-in function -`minusp' that was added in Emacs 31.1.") +This function is deprecated in favor of the built-in function `minusp' +that was added in Emacs 31.1.") (defalias 'cl-oddp #'oddp "Return t if INTEGER is odd. -This function is considered deprecated in favor of the built-in function -`oddp' that was added in Emacs 31.1.") +This function is deprecated in favor of the built-in function `oddp' +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.") +This function is 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/cl-seq.el b/lisp/emacs-lisp/cl-seq.el index 8e9207d079f..c0001ba353b 100644 --- a/lisp/emacs-lisp/cl-seq.el +++ b/lisp/emacs-lisp/cl-seq.el @@ -753,18 +753,21 @@ Return the sublist of LIST whose car is ITEM. (autoload 'cl--compiler-macro-member "cl-macs") ;;;###autoload -(defun cl-member-if (pred list &rest cl-keys) +(defalias 'cl-member-if #'member-if "Find the first item satisfying PREDICATE in LIST. Return the sublist of LIST whose car matches. \nKeywords supported: :key -\n(fn PREDICATE LIST [KEYWORD VALUE]...)" - (declare (important-return-value t)) - (apply #'cl-member nil list :if pred cl-keys)) +\n(fn PREDICATE LIST [KEYWORD VALUE]...) + +This function is deprecated in favour of the built-in `member-if' that +was added in Emacs 31.1.") ;;;###autoload (defun cl-member-if-not (pred list &rest cl-keys) "Find the first item not satisfying PREDICATE in LIST. Return the sublist of LIST whose car matches. +This function is deprecated in the Common Lisp standard. +Prefer `member-if' with a negated predicate. \nKeywords supported: :key \n(fn PREDICATE LIST [KEYWORD VALUE]...)" (declare (important-return-value t)) diff --git a/lisp/emulation/viper.el b/lisp/emulation/viper.el index dacd26d5b5f..8a381d7ed8c 100644 --- a/lisp/emulation/viper.el +++ b/lisp/emulation/viper.el @@ -793,14 +793,14 @@ It also can't undo some Viper settings." (cond ((and (viper-this-major-mode-requires-vi-state major-mode) (eq viper-current-state 'emacs-state)) (viper-mode)) - ((cl-member-if #'derived-mode-p viper-emacs-state-mode-list) + ((member-if #'derived-mode-p viper-emacs-state-mode-list) ;; not checking (eq viper-current-state 'emacs-state) ;; because viper-current-state could have gotten it by ;; default. We need viper-change-state-to-emacs here to have ;; the keymaps take effect. (viper-change-state-to-emacs)) - ((and (cl-member-if #'derived-mode-p - viper-insert-state-mode-list) + ((and (member-if #'derived-mode-p + viper-insert-state-mode-list) (not (eq viper-current-state 'insert-state))) (viper-change-state-to-insert)) )) ; with-current-buffer diff --git a/lisp/erc/erc-compat.el b/lisp/erc/erc-compat.el index ec1136e6478..ec209b28de2 100644 --- a/lisp/erc/erc-compat.el +++ b/lisp/erc/erc-compat.el @@ -88,11 +88,11 @@ See `replace-match' for explanations of FIXEDCASE and LITERAL." (define-obsolete-function-alias 'erc-make-obsolete-variable #'make-obsolete-variable "28.1") -;; Provide a simpler replacement for `cl-member-if' +;; Provide a simpler replacement for `member-if'. (defun erc-member-if (predicate list) "Find the first item satisfying PREDICATE in LIST. Return the sublist of LIST whose car matches." - (declare (obsolete cl-member-if "28.1")) + (declare (obsolete member-if "28.1")) (let ((ptr list)) (catch 'found (while ptr diff --git a/lisp/obsolete/cl.el b/lisp/obsolete/cl.el index 3c084511ad9..9b0aab7bd67 100644 --- a/lisp/obsolete/cl.el +++ b/lisp/obsolete/cl.el @@ -182,7 +182,6 @@ assoc-if-not assoc-if member-if-not - member-if merge stable-sort search diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index f73bdadef72..c2868a7c622 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -1622,13 +1622,13 @@ default) no filter is applied." finally (cl-return (cl-sort retval (if (cl-plusp n) #'< #'>) :key #'overlay-start)))) - (tail (cl-member-if (lambda (ov) - (if (cl-plusp n) - (> (overlay-start ov) - (point)) - (< (overlay-start ov) - (point)))) - ovs)) + (tail (member-if (lambda (ov) + (if (plusp n) + (> (overlay-start ov) + (point)) + (< (overlay-start ov) + (point)))) + ovs)) (chain (if flymake-wrap-around (if tail (progn (setcdr (last tail) ovs) tail) diff --git a/lisp/subr.el b/lisp/subr.el index 87ed399f2a3..e02d7751c93 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1182,14 +1182,40 @@ side-effects, and the argument LIST is not modified." (declare (compiler-macro (lambda (_) `(not (drop-while ,pred ,list))))) (not (drop-while pred list))) -(defun any (pred list) +(defun member-if (pred list &rest cl-args) "Non-nil if PRED is true for at least one element in LIST. -Returns the LIST suffix starting at the first element that satisfies PRED, -or nil if none does." - (declare (compiler-macro - (lambda (_) - `(drop-while (lambda (x) (not (funcall ,pred x))) ,list)))) - (drop-while (lambda (x) (not (funcall pred x))) list)) +Returns the suffix of LIST starting with the first element that +satisfies PRED, or nil if none do. + +Optional keyword argument `:key KEY-FN' is for backwards compatibility. +If present, call KEY-FN on elements of LIST before passing them to PRED. +In new code, prefer combining PRED and KEY. You can use something like + + (member-if (lambda (x) (foo (bar x))) items) + +instead of + + (member-if #\\='foo items :key #\\='bar) + +\(fn PRED LIST &key KEY)" + (declare + (compiler-macro + (lambda (_) + (pcase cl-args + ('nil `(drop-while (lambda (x) (not (funcall ,pred x))) ,list)) + (`(:key ,key-fn) + `(drop-while (lambda (x) (not (funcall ,pred (funcall ,key-fn x)))) + ,list)) + (_ (error "Invalid arguments to member-if: %s" cl-args)))))) + (pcase cl-args + ('nil (drop-while (lambda (x) (not (funcall pred x))) list)) + (`(:key ,key-fn) + (drop-while (lambda (x) (not (funcall pred (funcall key-fn x)))) list)) + (_ (error "Invalid arguments to member-if: %s" cl-args)))) + +;; This is good to have for improved readability in certain uses, but +;; use the traditional Lisp name for the underlying function. --spwhitton +(defalias 'any #'member-if) ;;;; Keymap support. diff --git a/lisp/textmodes/rst.el b/lisp/textmodes/rst.el index 22688f9b992..e1bee145f32 100644 --- a/lisp/textmodes/rst.el +++ b/lisp/textmodes/rst.el @@ -812,9 +812,9 @@ Return ADO if so or signal an error otherwise." "Return sublist of HDRS whose car's adornment equals that of SELF or nil." (cl-check-type self rst-Hdr) (let ((ado (rst-Hdr-ado self))) - (cl-member-if (lambda (hdr) - (rst-Ado-equal ado (rst-Hdr-ado hdr))) - hdrs))) + (member-if (lambda (hdr) + (rst-Ado-equal ado (rst-Hdr-ado hdr))) + hdrs))) (defun rst-Hdr-ado-map (selves) ;; testcover: ok. diff --git a/test/lisp/emacs-lisp/package-vc-tests.el b/test/lisp/emacs-lisp/package-vc-tests.el index 5ae36e79bcc..5f79c3d5522 100644 --- a/test/lisp/emacs-lisp/package-vc-tests.el +++ b/test/lisp/emacs-lisp/package-vc-tests.el @@ -1107,7 +1107,7 @@ contains key `:tags' use its value as tests tags." '(package-vc-tests-install-from-elpa package-vc-tests-install-from-spec)))) (should-not (package-vc-tests-log-buffer-exists 'doc pkg)) - (should (cl-member-if + (should (member-if (lambda (dir) (and (stringp dir) (string-prefix-p package-vc-tests-dir dir)))