aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias EngdegÄrd2025-10-10 15:39:15 +0200
committerMattias EngdegÄrd2025-10-20 11:39:16 +0200
commitd1b3eb7eec64ffb9f2d89efda21660cab92bcf0c (patch)
treef72ab3aa242a7c81d4e0bc449549f0ae92af231a
parentcfe3c1c840d279d584350d2426b572e211df7c93 (diff)
downloademacs-d1b3eb7eec64ffb9f2d89efda21660cab92bcf0c.tar.gz
emacs-d1b3eb7eec64ffb9f2d89efda21660cab92bcf0c.zip
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.
-rw-r--r--doc/lispref/lists.texi27
-rw-r--r--etc/NEWS5
-rw-r--r--lisp/subr.el14
-rw-r--r--test/lisp/subr-tests.el29
4 files changed, 75 insertions, 0 deletions
diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi
index da6d167c740..37ef8d46525 100644
--- a/doc/lispref/lists.texi
+++ b/doc/lispref/lists.texi
@@ -415,6 +415,33 @@ will return a list equal to @var{list}.
415@end example 415@end example
416@end defun 416@end defun
417 417
418@defun all pred list
419This function returns @code{t} if @var{pred} is true for all elements in
420@var{list}.
421
422@example
423@group
424(all #'numberp '(1 2 3 4)) @result{} t
425(all #'numberp '(1 2 a b 3 4)) @result{} nil
426(all #'numberp '()) @result{} t
427@end group
428@end example
429@end defun
430
431@defun any pred list
432This function returns non-@code{nil} if @var{pred} is true for at least
433one element in @var{list}. The returned value is the longest @var{list}
434suffix whose first element satisfies @var{pred}.
435
436@example
437@group
438(any #'symbolp '(1 2 3 4)) @result{} nil
439(any #'symbolp '(1 2 a b 3 4)) @result{} (a b 3 4)
440(any #'symbolp '()) @result{} nil
441@end group
442@end example
443@end defun
444
418@defun last list &optional n 445@defun last list &optional n
419This function returns the last link of @var{list}. The @code{car} of 446This function returns the last link of @var{list}. The @code{car} of
420this link is the list's last element. If @var{list} is null, 447this link is the list's last element. If @var{list} is null,
diff --git a/etc/NEWS b/etc/NEWS
index cf608578c34..94a01a63649 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -3143,6 +3143,11 @@ signal an error if they are given a non-integer.
3143These work like 'drop' and 'take' but use a predicate instead of counting. 3143These work like 'drop' and 'take' but use a predicate instead of counting.
3144 3144
3145+++ 3145+++
3146** New functions 'any' and 'all'.
3147These return non-nil for lists where any and all elements, respectively,
3148satisfy a given predicate.
3149
3150+++
3146** The 'defvar-local' macro second argument is now optional. 3151** The 'defvar-local' macro second argument is now optional.
3147This means that you can now call it with just one argument, like 3152This means that you can now call it with just one argument, like
3148'defvar', to declare a variable both special, and buffer-local. 3153'defvar', to declare a variable both special, and buffer-local.
diff --git a/lisp/subr.el b/lisp/subr.el
index 403e9dac376..216ad5eb4ab 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1176,6 +1176,20 @@ side-effects, and the argument LIST is not modified."
1176 (while (and list (funcall pred (car list))) 1176 (while (and list (funcall pred (car list)))
1177 (setq list (cdr list))) 1177 (setq list (cdr list)))
1178 list) 1178 list)
1179
1180(defun all (pred list)
1181 "Non-nil if PRED is true for all elements in LIST."
1182 (declare (compiler-macro (lambda (_) `(not (drop-while ,pred ,list)))))
1183 (not (drop-while pred list)))
1184
1185(defun any (pred list)
1186 "Non-nil if PRED is true for at least one element in LIST.
1187Returns the LIST suffix starting at the first element that satisfies PRED,
1188or nil if none does."
1189 (declare (compiler-macro
1190 (lambda (_)
1191 `(drop-while (lambda (x) (not (funcall ,pred x))) ,list))))
1192 (drop-while (lambda (x) (not (funcall pred x))) list))
1179 1193
1180;;;; Keymap support. 1194;;;; Keymap support.
1181 1195
diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el
index ae5932d96b3..fc980eae596 100644
--- a/test/lisp/subr-tests.el
+++ b/test/lisp/subr-tests.el
@@ -1545,5 +1545,34 @@ final or penultimate step during initialization."))
1545 (should (equal (funcall (subr--identity #'take-while) #'plusp ls) 1545 (should (equal (funcall (subr--identity #'take-while) #'plusp ls)
1546 '(3 2 1))))) 1546 '(3 2 1)))))
1547 1547
1548(ert-deftest subr-all ()
1549 (should (equal (all #'hash-table-p nil) t))
1550 (let ((ls (append '(3 2 1) '(0) '(-1 -2 -3))))
1551 (should (equal (all #'numberp ls) t))
1552 (should (equal (all (lambda (x) (numberp x)) ls) t))
1553 (should (equal (all #'plusp ls) nil))
1554 (should (equal (all #'bufferp ls) nil))
1555 (let ((z 9))
1556 (should (equal (all (lambda (x) (< x z)) ls) t))
1557 (should (equal (all (lambda (x) (> x (- z 9))) ls) nil))
1558 (should (equal (all (lambda (x) (> x z)) ls) nil)))
1559 (should (equal (funcall (subr--identity #'all) #'plusp ls) nil))
1560 (should (equal (funcall (subr--identity #'all) #'numberp ls) t))))
1561
1562(ert-deftest subr-any ()
1563 (should (equal (any #'hash-table-p nil) nil))
1564 (let ((ls (append '(3 2 1) '(0) '(-1 -2 -3))))
1565 (should (equal (any #'numberp ls) ls))
1566 (should (equal (any (lambda (x) (numberp x)) ls) ls))
1567 (should (equal (any #'plusp ls) ls))
1568 (should (equal (any #'zerop ls) '(0 -1 -2 -3)))
1569 (should (equal (any #'bufferp ls) nil))
1570 (let ((z 9))
1571 (should (equal (any (lambda (x) (< x z)) ls) ls))
1572 (should (equal (any (lambda (x) (< x (- z 9))) ls) '(-1 -2 -3)))
1573 (should (equal (any (lambda (x) (> x z)) ls) nil)))
1574 (should (equal (funcall (subr--identity #'any) #'minusp ls) '(-1 -2 -3)))
1575 (should (equal (funcall (subr--identity #'any) #'stringp ls) nil))))
1576
1548(provide 'subr-tests) 1577(provide 'subr-tests)
1549;;; subr-tests.el ends here 1578;;; subr-tests.el ends here