Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: "B. Pym" Newsgroups: comp.lang.lisp Subject: Re: counting nils in a list Date: Wed, 17 Jul 2024 04:12:35 -0000 (UTC) Organization: A noiseless patient Spider Lines: 74 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Injection-Date: Wed, 17 Jul 2024 06:12:35 +0200 (CEST) Injection-Info: dont-email.me; posting-host="c61a3943c524c0aaf773b15bc0bf86a0"; logging-data="1778031"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+e2WuDmIU1svIW1W81MJGM" User-Agent: XanaNews/1.18.1.6 Cancel-Lock: sha1:V0sRGpRbAy3Mau4CbaezbiJfZHk= Bytes: 2819 Pascal J. Bourguignon wrote: > > For example, if we have a function such as cut-list-if, which can cut > > a list between elements according to a predicate taking two successive > > elements in the list, such as: > > > > (cut-list-if (lambda (a b) (or a b)) > > '(nil nil nil a nil nil nil a b nil nil nil > > a b c nil nil nil a b c d e nil)) > > --> ((NIL NIL NIL) (A) (NIL NIL NIL) (A) (B) (NIL NIL NIL) (A) (B) (C) > > (NIL NIL NIL) (A) (B) (C) (D) (E) (NIL)) > > Oops, I forgot to present a CUT-LIST-IF: > > (defun cut-list-if (predicate list) > (loop > :with results = '() > :with sublist = '() > :for (a b) :on list > :do (if (funcall predicate a b) > (progn > (push a sublist) > (push sublist results) > (setf sublist '())) > (push a sublist)) > :finally (when sublist (push sublist results)) (return (reverse results)))) Buggy: * (cut-list-if (lambda (a b) (or (numberp a) (numberp b))) '(a b c 8 d e f 7 6 g 5 h i)) ((C B A) (8) (F E D) (7) (6) (G) (5) (I H)) Gauche Scheme (use gauche.collection) ;; fold2 ;; Correcting his bug. (define (cut-list-if predicate the-list) (receive (tmp res) (fold2 (lambda (a tmp res) (if (or (null? tmp) (not (predicate (car tmp) a))) (values (cons a tmp) res) (values (list a) (cons tmp res)))) '() '() the-list) (reverse (map reverse (cons tmp res))))) (cut-list-if (lambda (a b) (or (number? a) (number? b))) '(a b c 8 d e f 7 6 g 5 h i 5)) ===> ((a b c) (8) (d e f) (7) (6) (g) (5) (h i) (5)) (cut-list-if (lambda (a b) (or a b)) '(#f #f #f a #f #f #f a b #f #f #f a b c #f #f #f a b c d e #f)) ===> ((#f #f #f) (a) (#f #f #f) (a) (b) (#f #f #f) (a) (b) (c) (#f #f #f) (a) (b) (c) (d) (e) (#f)) (cut-list-if > '(0 2 3 5 4 5 6)) ===> ((0 2 3 5) (4 5 6))