(define (factorial n k) (if (= n 0) k (factorial (- n 1) (* k n)))) (define (length s) (if (null? s) 0 (+ 1 (length (cdr s))))) (define (length-tail s) (define (length-iter s n) (if (null? s) n (length-iter (cdr s) (+ 1 n)))) (length-iter s 0)) (define (reduce fn s start) (if (null? s) start (reduce fn (cdr s) (fn start (car s))))) (define (reverse s) (define (reverse-iter s r) (if (null? s) r (reverse-iter (cdr s) (cons (car s) r)))) (reverse-iter s nil)) (define (map fn s) (define (map-iter fn s m) (if (null? s) m (map-iter fn (cdr s) (cons (fn (car s)) m)))) (reverse (map-iter fn s nil))) ;;; Tests (define (assert-equal v1 v2) (if (equal? v1 v2) (print 'ok) (print (list v2 'does 'not 'equal v1)))) (define square (lambda (x) (* x x))) (assert-equal 360 (factorial 5 3)) (assert-equal 4 (length '(5 6 7 8))) (assert-equal 4 (length-tail '(5 6 7 8))) (assert-equal 1680 (reduce * '(5 6 7 8) 1)) (assert-equal '(5 4 3 2) (reduce (lambda (x y) (cons y x)) '(3 4 5) '(2))) (assert-equal '(8 7 6 5) (reverse '(5 6 7 8))) (assert-equal '(25 36 49 64) (map square '(5 6 7 8)))