[scm/utilities] even more efficient list-flatten functions

because:

* list? is O(N), because it needs to test for an improper
list. improper lists are lists whose last pair's cdr cell is not
'(). null? and pair? are both O(1).

* avoids reverse which is also O(N): guile has unlimited stack
therefore we can do non-tail-call loop first to pass as parameter to
the tail-call loop. this removes the need for prepend-and-reverse.
This commit is contained in:
Christopher Lam 2019-11-18 21:19:50 +08:00
parent 043abcb436
commit fbc7c9027e
2 changed files with 8 additions and 7 deletions

View File

@ -107,7 +107,8 @@
(define (gnc:html-document-tree-collapse . tree) (define (gnc:html-document-tree-collapse . tree)
(let lp ((e tree) (accum '())) (let lp ((e tree) (accum '()))
(cond ((list? e) (fold lp accum e)) (cond ((null? e) accum)
((pair? e) (fold lp accum e))
((string? e) (cons e accum)) ((string? e) (cons e accum))
(else (cons (object->string e) accum))))) (else (cons (object->string e) accum)))))

View File

@ -212,14 +212,14 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; flattens an arbitrary deep nested list into simple list. this is ;; flattens an arbitrary deep nested list into simple list. this is
;; probably the most efficient algorithm available. '(1 2 (3 4)) --> ;; probably the most efficient algorithm available. '(1 2 (3 4)) -->
;; '(1 2 3 4) ;; '(1 2 3 4) thanks to manumanumanu on #guile
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (gnc:list-flatten . lst) (define (gnc:list-flatten . lst)
(reverse (let loop ((lst lst) (acc '()))
(let lp ((e lst) (accum '())) (cond
(if (list? e) ((null? lst) acc)
(fold lp accum e) ((pair? lst) (loop (car lst) (loop (cdr lst) acc)))
(cons e accum))))) (else (cons lst acc)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; compatibility hack for fixing guile-2.0 string handling. this code ;; compatibility hack for fixing guile-2.0 string handling. this code