- Hacked append-reverse! so that it won't blow up on improper lists.
- Hacked delete so that it shares storage when possible -- it doesn't always copy the entire list. For example, (delete lis (lambda (x) #f)) returns lis, allocating no new list structure. (It allocates stack frames, of course.)
This commit is contained in:
parent
29c3ebf99a
commit
878c07f4c1
|
@ -170,23 +170,34 @@
|
|||
(define (delq thing list)
|
||||
(delete (lambda (x) (eq? x thing)) list))
|
||||
|
||||
(define (delete pred in-list)
|
||||
(let loop ((list in-list) (res '()))
|
||||
(cond ((null? list)
|
||||
in-list)
|
||||
((pred (car list))
|
||||
(append-reverse! res (cdr list)))
|
||||
(else
|
||||
(loop (cdr list) (cons (car list) res))))))
|
||||
|
||||
(define (append-reverse! l1 l2)
|
||||
(let loop ((list l1) (res l2))
|
||||
(cond ((null? list)
|
||||
res)
|
||||
(else
|
||||
(let ((next (cdr list)))
|
||||
(set-cdr! list res)
|
||||
(loop next list))))))
|
||||
|
||||
(if (pair? list)
|
||||
(let ((next (cdr list)))
|
||||
(set-cdr! list res)
|
||||
(loop next list))
|
||||
res)))
|
||||
|
||||
;; This DELETE shares the longest tail of L that has no deleted elements.
|
||||
;; If we had multi-continuation calls, this could be made more efficient.
|
||||
|
||||
(define (delete pred l)
|
||||
(call-with-values (lambda ()
|
||||
;; (recur l) returns L with (pred x) values deleted.
|
||||
;; It also returns a flag NO-DEL? if the returned value
|
||||
;; is EQ? to L, i.e. if it didn't delete anything.
|
||||
(let recur ((l l))
|
||||
(if (pair? l)
|
||||
(let ((x (car l))
|
||||
(tl (cdr l)))
|
||||
(if (pred x)
|
||||
(call-with-values (lambda () (recur tl))
|
||||
(lambda (ans no-del?)
|
||||
(values ans #f))) ; Deleted X.
|
||||
(call-with-values (lambda () (recur tl))
|
||||
(lambda (ans no-del?)
|
||||
(if no-del?
|
||||
(values l #t)
|
||||
(values (cons x ans) #f))))))
|
||||
(values '() #t))))
|
||||
(lambda (ans no-del?) ans)))
|
||||
|
|
Loading…
Reference in New Issue