; let's summarize our list functions again and look at how they are used. ; we can construct lists using cons and list (cons 'a '(b c)) ; creates a proper list (cons 'a 'b) ; creates a dotted pair (list 1 2 3 4 5) (list 'a 2 '(-1 b) "hello world") ; here are some "tricks" for creating lists (define (foo x . rest) (cons x rest)) (define bar (lambda x x)) (foo '(a b) '(c d e)) (foo 'a 'b 'c 'd 'e) (bar '(a b) '(c d e)) (bar 'a 'b 'c 'd 'e) ; so we can define the 'list' function above as simply: (define list (lambda x x)) (list 1 2 3 4 5) (list 'a 2 '(-1 b) "hello world") ; and the list predicates: (list? '()) (empty? '()) (null? '()) (eq? '() '()) (equal? '(a b) '(a b)) ; We already know about the primitive functions car and cdr ; that work on both proper lists and improper lists (car '(1 2 3 4 5)) (cdr '(a b c d e)) (car '(a . b)) (cdr '(a . b)) ; they are used to implement related list functions: (define (caar lst) (car (car lst))) (define (cddr lst) (cdr (cdr lst))) (define (cadr lst) (car (cdr lst))) ; We can use foldl to compute the lenght of a list ; (foldl f base (list x_1 ... x_n)) = (f x_n ... (f x_1 base)) (define (length lst) (foldl (lambda (x n) (+ n 1)) 0 lst)) (length '(a b c d e)) ; append is similar but operates on two lists: lst1 and lst2 ; and appends lst2 to lst1. So we just cons each element of ; lst1 onto lst2 in reverse order (define (append lst1 lst2) (foldl cons lst2 (reverse lst1))) (append '(1 2 3) '(a b c d)) ; Similar to folding over a list there is a function ; called reduce that evaluates the elements of a list ; from left to right but the order of the arguments is ; different than with foldl: ; ; (reduce f x (e1 e2 ... en)) => (f x (f e1 (...(f en-1 en)...)) (define reduce (lambda (f x lst) (if (null? lst) x (f x (reduce f (car lst) (cdr lst)))))) (reduce + 0 '(1 2 3 4 5)) ; and of course the useful function map that maps ; another function over a list. Notice that ; we use foldr instead of foldl. Why? ; (foldr f base (list x_1 ... x_n)) = (f x_1 ... (f x_n base)) (define map (lambda (f lst) (foldr (lambda (x y) (cons (f x) y)) '() lst)))