;;; Michael Wollowski (define (rl) (load "day8.ss")) ;;; Let's have a look at three recursive functions on lists ;;; All three are very similar. ;;; All three follows the same GRAMMAR! (define sum (lambda (ls) (if (null? ls) 0 (+ (car ls) (sum (cdr ls)))))) (define product (lambda (ls) (if (null? ls) 1 (* (car ls) (product (cdr ls)))))) (define length (lambda (ls) (if (null? ls) 0 (+ 1 (length (cdr ls)))))) ;;; Let's see whether we can abstract them into one function! ;;; Let's start with abstracting the value of the base case. (define sum (lambda (ls init) (if (null? ls) init (+ (car ls) (sum (cdr ls) init))))) (define product (lambda (ls init) (if (null? ls) init (* (car ls) (product (cdr ls) init))))) (define length (lambda (ls init) (if (null? ls) init (+ 1 (length (cdr ls) init))))) ;;; All three use a binary function involving the recursive call. ;;; Let's continue by abstracting the binary function. (define list-recur (lambda (ls init f) (if (null? ls) init (f (car ls) (list-recur (cdr ls) init f))))) ;;; We now can define length, sum and product, in terms of list-recur (define sum (lambda (ls) (list-recur ls 0 +))) (define product (lambda (ls) (list-recur ls 1 *))) (define length (lambda (ls) (list-recur ls 0 (lambda (x y) (+ 1 y))))) ;;; How about some bonus functions? (define foo (lambda (ls) (list-recur ls '() (lambda (x y) (cons x y))))) (define boo (lambda (ls g) (list-recur ls '() (lambda(x y) (cons (g x) y))))) (define member-item (lambda (item ls) (list-recur ls 0 (lambda (x y) (if (eq? x item) (+ 1 y) y))))) ;;; Is 2 a member of ls? (define member2 (lambda (ls) (member-item 2 ls))) ;;; Alternate way of asking whether 2 a member of ls? (define member2 (lambda (ls) (list-recur ls 0 (lambda (x y) (if (eq? x 2) (+ 1 y) y))))) ;;; Better code!!!! (define list-recur-tail (lambda (ls init f) (if (null? ls) init (list-recur-tail (cdr ls) (f (car ls) init) f)))) ;;; Best!!!!! (define list-recur-cool (lambda (f init) (letrec ([g (lambda (ls) (if (null? ls) init (f (car ls) (g (cdr ls)))))]) g)))