I have a version that uses only the "first principle" operations and is effective (more than one pass through any of the lists is not required, unlike append based solutions) append
He does this by defining two simple building blocks ( fold and reverse ), and then defining flatten (and his assistant, reverse-flatten-into ) on top of these (and notice how each function is one or two long lines):
;; Similar to SRFI 1 fold (define (fold1 kons knil lst) (if (null? lst) knil (fold1 kons (kons (car lst) knil) (cdr lst)))) ;; Same as R5RS reverse (define (reverse lst) (fold1 cons '() lst)) ;; Helper function (define (reverse-flatten-into x lst) (if (pair? x) (fold1 reverse-flatten-into lst x) (cons x lst))) (define (flatten . lst) (reverse (reverse-flatten-into lst '())))
Only external functions are used: cons , car , cdr , null? and pair? .
The key concept of this function is that fold is a very powerful operation and should be part of any Schemer toolkit. And, as can be seen from the above code, it is so easy to build from the first principles!
source share