emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/cl-lib-improvements 94849ba35f4: seq.el: experimental seq.el spe


From: João Távora
Subject: feature/cl-lib-improvements 94849ba35f4: seq.el: experimental seq.el speedups
Date: Thu, 16 Nov 2023 09:01:33 -0500 (EST)

branch: feature/cl-lib-improvements
commit 94849ba35f40393362050b5937578dcf3076b4bf
Author: João Távora <joaotavora@gmail.com>
Commit: João Távora <joaotavora@gmail.com>

    seq.el: experimental seq.el speedups
    
    * lisp/emacs-lisp/seq.el (seq-contains-p): Rework.
    (seq-uniq): Rework
    (seq-difference-2): New function
    (seq-difference-3): New function
---
 lisp/emacs-lisp/seq.el | 62 ++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 55 insertions(+), 7 deletions(-)

diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el
index 346250c1d35..832a49d7845 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -440,12 +440,45 @@ whether an element was found or not."
 (cl-defgeneric seq-contains-p (sequence elt &optional testfn)
   "Return non-nil if SEQUENCE contains an element \"equal\" to ELT.
 \"Equality\" is defined by the function TESTFN, which defaults to `equal'."
+  (cond
+   ((and (listp sequence) (or (null testfn) (eq testfn 'equal)))
+    (member elt sequence))
+   ((and (listp sequence) (eq testfn 'eq))
+    (memq elt sequence))
+   (t
     (catch 'seq--break
-      (seq-doseq (e sequence)
-        (let ((r (funcall (or testfn #'equal) e elt)))
-          (when r
-            (throw 'seq--break r))))
-      nil))
+    (seq-doseq (e sequence)
+      (let ((r (funcall (or testfn #'equal) e elt)))
+        (when r
+          (throw 'seq--break r))))
+    nil)))
+  )
+
+;; (cl-defmethod seq-contains-p ((sequence list) elt &optional testfn)
+;;   (cond
+;;    ((or (null testfn) (eq testfn 'equal))
+;;     (member elt sequence))
+;;    ((eq testfn 'eq)
+;;     (memq elt sequence))
+;;    (t
+;;     (cl-call-next-method))))
+
+(cl-defgeneric seq-contains-pred (sequence &optional testfn)
+  (cond
+   ((and (listp sequence) (or (null testfn) (eq testfn 'equal)))
+    #'member)
+   ((and (listp sequence) (eq testfn 'eql))
+    #'memql)
+   ((and (listp sequence) (eq testfn 'eq))
+    #'memq)
+   (t
+    (lambda (elt sequence)
+      (catch 'seq--break
+        (seq-doseq (e sequence)
+          (let ((r (funcall testfn e elt)))
+            (when r
+              (throw 'seq--break r))))
+        nil)))))
 
 (cl-defgeneric seq-set-equal-p (sequence1 sequence2 &optional testfn)
   "Return non-nil if SEQUENCE1 and SEQUENCE2 contain the same elements.
@@ -488,9 +521,10 @@ The result is a list of (zero-based) indices."
 (cl-defgeneric seq-uniq (sequence &optional testfn)
   "Return a list of the elements of SEQUENCE with duplicates removed.
 TESTFN is used to compare elements, and defaults to `equal'."
-  (let ((result '()))
+  (let ((result '())
+        (pred (seq-contains-pred testfn)))
     (seq-doseq (elt sequence)
-      (unless (seq-contains-p result elt testfn)
+      (unless (funcall pred elt result)
         (setq result (cons elt result))))
     (nreverse result)))
 
@@ -574,6 +608,20 @@ defaults to `equal'."
               (seq-reverse sequence1)
               '()))
 
+(cl-defgeneric seq-difference-2 (sequence1 sequence2 &optional testfn)
+  "Return list of all the elements that appear in SEQUENCE1 but not in 
SEQUENCE2.
+\"Equality\" of elements is defined by the function TESTFN, which
+defaults to `equal'."
+  (seq-filter
+   (lambda (elt) (not (seq-contains-p sequence2 elt testfn)))
+   sequence1))
+
+(cl-defgeneric seq-difference-3 (sequence1 sequence2 &optional testfn)
+  (let ((pred (seq-contains-pred sequence2 testfn)))
+    (seq-filter
+     (lambda (elt) (not (funcall pred elt sequence2)))
+     sequence1)))
+
 ;;;###autoload
 (cl-defgeneric seq-group-by (function sequence)
   "Apply FUNCTION to each element of SEQUENCE.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]