guile-commits
[Top][All Lists]
Advanced

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

[Guile-commits] 13/17: srfi-1 lset-difference: use remove


From: Rob Browning
Subject: [Guile-commits] 13/17: srfi-1 lset-difference: use remove
Date: Tue, 30 Jul 2024 20:41:54 -0400 (EDT)

rlb pushed a commit to branch main
in repository guile.

commit 51e15d448f705a7aa0aa2f26744f9b2b793535d2
Author: Rob Browning <rlb@defaultvalue.org>
AuthorDate: Sun Jul 21 10:46:09 2024 -0500

    srfi-1 lset-difference: use remove
    
    * module/srfi/srfi-1.scm (lset-difference): rely on remove like
    lset-difference!; in addition to being simpler, this allows sharing a
    common tail.
---
 module/srfi/srfi-1.scm | 36 +++++++++++++++++++++++++-----------
 1 file changed, 25 insertions(+), 11 deletions(-)

diff --git a/module/srfi/srfi-1.scm b/module/srfi/srfi-1.scm
index 01413c963..793185e1d 100644
--- a/module/srfi/srfi-1.scm
+++ b/module/srfi/srfi-1.scm
@@ -1301,18 +1301,32 @@ given REST parameters."
        (lp (cdr l) (cons (car l) acc))
        (lp (cdr l) acc)))))
 
-(define (lset-difference = list1 . rest)
-  (check-arg procedure? = lset-difference)
-  (if (null? rest)
-    list1
-    (let lp ((l list1) (acc '()))
-      (if (null? l)
-       (reverse! acc)
-       (if (any (lambda (ll) (member (car l) ll =)) rest)
-         (lp (cdr l) acc)
-         (lp (cdr l) (cons (car l) acc)))))))
+(define (lset-difference = lset . removals)
+  "Return @var{lst} with any elements in the lists in @var{removals}
+removed (ie.@: subtracted).  For only one @var{lst} argument, just that
+list is returned.
+
+The given @var{equal} procedure is used for comparing elements, called
+as @code{(@var{equal} elem1 elemN)}.  The first argument is from
+@var{lst} and the second from one of the subsequent lists.  But exactly
+which calls are made and in what order is unspecified.
+
+@example
+(lset-difference eqv? (list 'x 'y))           @result{} (x y)
+(lset-difference eqv? (list 1 2 3) '(3 1))    @result{} (2)
+(lset-difference eqv? (list 1 2 3) '(3) '(2)) @result{} (1)
+@end example
 
-;(define (fold kons knil list1 . rest)
+The result may share a common tail with @var{lset}."
+  ;; REVIEW: if we think they're actually going to be sets, i.e. no
+  ;; duplicates, then might it be better to just reduce via per-set
+  ;; delete -- more transient allocation but maybe a lot less work?
+  (check-arg procedure? = lset-difference)
+  (cond
+   ((null? lset) lset)
+   ((null? removals) lset)
+   (else (remove (lambda (x) (any (lambda (s) (member x s =)) removals))
+                 lset))))
 
 (define (lset-xor = . rest)
   (check-arg procedure? = lset-xor)



reply via email to

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