;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; list routines for lecture on section 2.2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; list length ;;; length : list of T --> integer (define (length lst) (if (null? lst) 0 (+ 1 (length (cdr lst))))) ;;; iterative list length (define (length lst) (define (iter ls count) (if (null? ls) count (length-iter (cdr ls) (+ 1 count)))) (iter lst 0)) ;;; nth element (1-based) -- Scheme's list-ref is 0 based ! ;;; nth : list of T, integer --> T (define (nth lst n) (cond ((null? lst) (error "nth -- fell off end of list")) ((<= n 0) (error "nth -- list items start from 1")) ((= n 1) (car lst)) (else (nth (cdr lst) (-n 1))))) ;;; Scale elements of a list of numbers by some number ;;; scale-list : list of number, number --> list of number (define (scale-list lst n) (if (null? lst) '() (cons (* n (car lst)) (scale-list (cdr lst) n)))) ;;; Pattern from scale-list: map. ;;; map : (S --> T), list of S --> list of T (define map (f lst) (if (null? lst) '() (cons (f (car lst)) (map f (cdr lst))))) ;;; Attempt to write iterative map reverses the order of the output! (define (revmap f lst) (define (iter lst new) (if (null? lst) new (iter (cdr lst) (cons (f (car lst)) new)))) (iter lst '())) ;;; append two lists (define (append lst1 lst2) (if (null? lst1) (lst2) (cons (car lst1) (append (cdr lst1) lst2)))) ;;; reverse a list (1) (define (reverse lst) (if (null? lst) '() (append (reverse (cdr lst)) (list (car lst))))) ;;; reverse a list (2) (instance of revmap pattern) (define (reverse lst) (define (iter lst new) (if (null? lst) new (iter (cdr lst) (cons (car lst) new)))) (iter lst '())) ;;; Keep only elements of list that satisfy a predicate ;;; filter : (A --> boolean), list of A --> list of A (define (filter predicate lst) (cond ((null? lst) '()) ((p (car lst)) (cons (car lst) (filter p (cdr lst)))) (else (filter p (cdr lst))))) ;;; Fold an operation over a list associating right ;;; This generalizes the pattern of length, scale-list, map, append, filter... ;;; accumulate : ((A, B) --> B), B, list of A --> B (define (accumulate op base-value lst) (if (null? lst) base-value (op (car lst) (accum op base-value (cdr lst))))) ;;; Fold an operation over a list associating left ;;; This generalizes reverse, revmap... ;;; type same as accumulate. (define (fold-left op base-value lst) (define (iter lst new) (if (null? lst) new (iter (cdr lst) (op new (car lst))))) (iter lst base-value))