1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-06 06:20:55 -08:00

Add any and all (bug#79611)

* lisp/subr.el (all, any): New.
* test/lisp/subr-tests.el (subr-all, subr-any): New tests.
* doc/lispref/lists.texi (List Elements): Document.
* etc/NEWS: Announce.
This commit is contained in:
Mattias Engdegård 2025-10-10 15:39:15 +02:00
parent cfe3c1c840
commit d1b3eb7eec
4 changed files with 75 additions and 0 deletions

View file

@ -415,6 +415,33 @@ will return a list equal to @var{list}.
@end example @end example
@end defun @end defun
@defun all pred list
This function returns @code{t} if @var{pred} is true for all elements in
@var{list}.
@example
@group
(all #'numberp '(1 2 3 4)) @result{} t
(all #'numberp '(1 2 a b 3 4)) @result{} nil
(all #'numberp '()) @result{} t
@end group
@end example
@end defun
@defun any 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
@end group
@end example
@end defun
@defun last list &optional n @defun last list &optional n
This function returns the last link of @var{list}. The @code{car} of 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, this link is the list's last element. If @var{list} is null,

View file

@ -3142,6 +3142,11 @@ signal an error if they are given a non-integer.
** New functions 'drop-while' and 'take-while'. ** New functions 'drop-while' and 'take-while'.
These work like 'drop' and 'take' but use a predicate instead of counting. 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,
satisfy a given predicate.
+++ +++
** The 'defvar-local' macro second argument is now optional. ** The 'defvar-local' macro second argument is now optional.
This means that you can now call it with just one argument, like This means that you can now call it with just one argument, like

View file

@ -1176,6 +1176,20 @@ side-effects, and the argument LIST is not modified."
(while (and list (funcall pred (car list))) (while (and list (funcall pred (car list)))
(setq list (cdr list))) (setq list (cdr list)))
list) list)
(defun all (pred list)
"Non-nil if PRED is true for all elements in LIST."
(declare (compiler-macro (lambda (_) `(not (drop-while ,pred ,list)))))
(not (drop-while pred list)))
(defun any (pred list)
"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))
;;;; Keymap support. ;;;; Keymap support.

View file

@ -1545,5 +1545,34 @@ final or penultimate step during initialization."))
(should (equal (funcall (subr--identity #'take-while) #'plusp ls) (should (equal (funcall (subr--identity #'take-while) #'plusp ls)
'(3 2 1))))) '(3 2 1)))))
(ert-deftest subr-all ()
(should (equal (all #'hash-table-p nil) t))
(let ((ls (append '(3 2 1) '(0) '(-1 -2 -3))))
(should (equal (all #'numberp ls) t))
(should (equal (all (lambda (x) (numberp x)) ls) t))
(should (equal (all #'plusp ls) nil))
(should (equal (all #'bufferp ls) nil))
(let ((z 9))
(should (equal (all (lambda (x) (< x z)) ls) t))
(should (equal (all (lambda (x) (> x (- z 9))) ls) nil))
(should (equal (all (lambda (x) (> x z)) ls) nil)))
(should (equal (funcall (subr--identity #'all) #'plusp ls) nil))
(should (equal (funcall (subr--identity #'all) #'numberp ls) t))))
(ert-deftest subr-any ()
(should (equal (any #'hash-table-p nil) nil))
(let ((ls (append '(3 2 1) '(0) '(-1 -2 -3))))
(should (equal (any #'numberp ls) ls))
(should (equal (any (lambda (x) (numberp x)) ls) ls))
(should (equal (any #'plusp ls) ls))
(should (equal (any #'zerop ls) '(0 -1 -2 -3)))
(should (equal (any #'bufferp ls) nil))
(let ((z 9))
(should (equal (any (lambda (x) (< x z)) ls) ls))
(should (equal (any (lambda (x) (< x (- z 9))) ls) '(-1 -2 -3)))
(should (equal (any (lambda (x) (> x z)) ls) nil)))
(should (equal (funcall (subr--identity #'any) #'minusp ls) '(-1 -2 -3)))
(should (equal (funcall (subr--identity #'any) #'stringp ls) nil))))
(provide 'subr-tests) (provide 'subr-tests)
;;; subr-tests.el ends here ;;; subr-tests.el ends here