(define (rl) (load "boo.ss")) (define fac-letrec (lambda (n) (letrec ((facT (lambda (n accu) (if (zero? n) accu (facT (- n 1) (* accu n)))))) (facT n 1)))) (define odd? (lambda (n) (if (zero? n) #f (even? (- n 1))))) (define even? (lambda (n) (if (zero? n) #t (odd? (- n 1))))) (define odd-dumb? (lambda (n) (letrec ([odd? (lambda (n) (if (zero? n) #f (even? (- n 1))))] [even? (lambda (n) (if (zero? n) #t (odd? (- n 1))))]) (odd? n)))) (define fac-named-let (lambda (n) (let loop ([n n][accu 1]) (if (zero? n) accu (loop (- n 1) (* accu n)))))) ;;; Data abstraction ;;; Two procedures which differ only by name and the constant ;;; added to the parameter (define add1 (lambda (n) (+ n 1))) (define add3 (lambda (n) (+ n 3))) ;;; Generalize them by abstracting from the differences. ;;; You need to add a parameter (define add (lambda (n m) (+ n m))) ;;; Function Abstraction ;;; Suppose we have a similar procedure which multiplies ;;; two numbers: (define multiply (lambda (n m) (* n m))) ;;; Again, the only differences are the names and in this case the ;;; operator. Use abstraction again: (define arithmetic (lambda (n m f) (f n m))) ;;; Notice how seamless data and function abstraction work in Scheme ;;; Shadowing (define fac (lambda (n) (if (= n 0) 1 (* n (fac (- n 1))))))