;; The previous examples are from a previous class (Day 4?) ;; Original version of factorial function: (define fact ; standard factorial function. (lambda (n) (if (zero? n) 1 (* n (fact (- n 1)))))) (define fact-tail ; tail-recursive version with accumulator (lambda (n accum) (if (zero? n) accum (fact-tail (- n 1) (* n accum))))) (define factorial (lambda (n) (fact-tail n 1))) ;; Now a Day 5 experiment. ;; For each expression, try to predict what will happen. ;; Then execute we will to see what really happens. ;; Can you explain what you see? (define f fact) (f 5) (define fact (lambda (n) "Abe Lincoln elected President")) (fact 1860) (f 1860) ; We'd like to write fact so that we can rename it safely: ; (defnie g fact) ; (define fact whatever) and still have g work. ; It would also be nice to add the efficiency-enhancing acccumulator ; How about this? (define fact (let ([fact-tail (lambda (n accum) (if (zero? n) accum (fact-tail (- n 1) (* n accum))))]) (lambda (n) (fact-tail n 1)))) (fact 5) ; Solution? (define fact (letrec ([fact-tail (lambda (n prod) (if (zero? n) prod (fact-tail (sub1 n) (* n prod))))]) (lambda (n) (fact-tail n 1)))) ; another letrec example (define odd? (letrec ([odd? (lambda (n) (if (zero? n) #f (even? (sub1 n))))] [even? (lambda (n) (if (zero? n) #t (odd? (sub1 n))))]) (lambda (n) (odd? n)))) (odd? 6) ; trace-lambda can be useful ;; Named let version of fact (define fact (lambda (n) (let fact-tail ([x n] [prod 1]) (if (zero? x) prod (fact-tail (sub1 x) (* prod x)))))) ; This is a shorthand for : (define fact (lambda (n) (letrec ([fact-tail (lambda (x prod) (if (zero? x) prod (fact-tail (sub1 x) (* x prod))))]) (fact-tail n 1)))) ; Note that let and named-let have the same name ; but very different semantics. ; The difference in syntax is the "name" part ; (in this case, the name is "fact-tail"). ; In this example, there is nothing special ; about the name "fact-tail": it is simply a name ; that I chose for this example. ; Think of it as initializing x by n and prod by 1, ; then ececuting the body (in this case, the "if").