bug#81581: [PATCH 1/1] Add a LESSP argument to 'seq-min' and 'seq-max'

Philip Kaludercic <[email protected]>
Newsgroups gmane.emacs.bugs
Message-ID <[email protected]>
Finding the maximal or minimal element of a list according to some
comparative metric has been something I have run into multiple times
(just now, I was trying to find the newest version of a package
according to `version-list-<'), but always implemented by hand.  I would
like to propose extending the existing seq-min and seq-max functions
with an optional argument, along the lines of `sort':
0001-Add-a-LESSP-argument-to-'seq-min'-and-'seq-max'.patch (text/x-patch, 2 KB)
From bde439aec5e97f1677e99b8fdea0d2a0fa97fe09 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <[email protected]>
Date: Sat, 8 Aug 2026 21:56:57 +0200
Subject: [PATCH 1/1] Add a LESSP argument to 'seq-min' and 'seq-max'

* lisp/emacs-lisp/seq.el (seq-min, seq-max): Add an optional
argument allowing the generalization of sequence to more than
just numerical data.
---
 lisp/emacs-lisp/seq.el | 32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el
index b8f35c10def..87f5e3c0bd3 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -604,16 +604,36 @@ seq-group-by
    (seq-reverse sequence)
    nil))
 
-(cl-defgeneric seq-min (sequence)
+(cl-defgeneric seq-min (sequence &optional lessp)
   "Return the smallest element of SEQUENCE.
-SEQUENCE must be a sequence of numbers or markers."
-  (apply #'min (seq-into sequence 'list)))
+Values are compared according to the optional parameter LESSP, which
+defaults to `value<'."
+  (unless lessp (setq lessp #'value<))
+  (let ((fresh (eval-when-compile (make-symbol "fresh"))))
+    (seq-reduce
+     (lambda (acc elt)
+       (cond
+        ((eq acc fresh) elt)
+        ((funcall lessp acc elt) acc)
+        (t elt)))
+     sequence
+     fresh)))
 
 ;;;###autoload
-(cl-defgeneric seq-max (sequence)
+(cl-defgeneric seq-max (sequence &optional lessp)
   "Return the largest element of SEQUENCE.
-SEQUENCE must be a sequence of numbers or markers."
-  (apply #'max (seq-into sequence 'list)))
+Values are compared according to the optional parameter LESSP, which
+defaults to `value<'."
+  (unless lessp (setq lessp #'value<))
+  (let ((fresh (eval-when-compile (make-symbol "fresh"))))
+    (seq-reduce
+     (lambda (acc elt)
+       (cond
+        ((eq acc fresh) elt)
+        ((funcall lessp acc elt) elt)
+        (t acc)))
+     sequence
+     fresh)))
 
 (defun seq--count-successive (pred sequence)
   "Count successive elements in SEQUENCE for which PRED returns non-nil."
-- 
2.47.3
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.