150 likes | 461 Views
Recursion in Scheme. recursion is the basic means for expressing repetition some recursion is on numbers factorial fibonacci some recursion is on structures list length member of a list. Basics of recursion. The basic elements of a recursive function are: a base case:
E N D
Recursion in Scheme • recursion is the basic means for expressing repetition • some recursion is on numbers • factorial • fibonacci • some recursion is on structures • list length • member of a list
Basics of recursion The basic elements of a recursive function are: • a base case: • the condition for using the base case • the solution in the base case • a recursive case • the condition for using the recursive case • the solution in the recursive case • decomposes the problem into smaller subproblems • recursively solves subproblems • combines subproblem solutions to solve overall problem
fact(0) = 1 fact(n) = n * fact(n-1) Example:factorial ;;; Scheme implementation (define fact (lambda (n) (if (= n 0) 1 (* n (fact (- n 1))) )))
Example:factorial fact(0) = 1 fact(n) = n * fact(n-1) (* ML implementation *) fun fact(0) = 1 | fact(n) = n * fact(n-1);
Example:fibonacci fib(0) = 1 fib(1) = 1 fib(n) = fib(n-1) + fib(n-2) ;;; Scheme implementation (define fib (lambda (n) (if (<= n 1) 1 (+ (fib (- n 1))(fib (- n 2))) )))
Example:fibonacci fib(0) = 1 fib(1) = 1 fib(n) = fib(n-1) + fib(n-2) (* ML implementation *) fun fib(0) = 1 | fib(1) = 1 | fib(n) = fib(n-1) + fib(n-2);
Example:list length len( empty list ) = 0 len( non-empty list L) = 1 + len(tail of L) ;;; Scheme implementation (define len (lambda (lst) (if (null? lst) 0 (+ 1 (len (cdr lst))) )))
Example:list length len( empty list ) = 0 len( non-empty list L) = 1 + len(tail of L) (* ML implementation *) fun len([])= 0 | len(hd::tl) = 1 + len(tl);
member(item, empty list ) = false member(item, non-empty list L) = true if item is (first L), member(item,tail of L) otherwise Example:member ;;; Scheme implementation (define member (lambda (item lst) (if (null? lst) #f (or ;;; short circuit evaluation (eq? item (car lst)) (member item (cdr lst)) ))))
Example:member member(item, empty list ) = false member(item, non-empty list L) = true if item is (first L), member(item,tail of L) otherwise (* ML implementation *) fun member(item,[])= false | member(item, hd::tl) = (item=hd) orelse member(item,tl);
Tail recursion • Tail recursion is a special case of recursion in which the recursive call is the last thing done in a function. • This sort of recursion can be optimized to reuse the environment which binds the parameters of the recursive function to their arguments. • This is a special case of what is known as last-call optimization.
Writing tail recursive functions • To make a recursive function tail recursive we transform a recursion with work remaining to do after the recursive call into a recursion where that work is done prior to the call. • Let’s use factorial as an example.
fact(0) = 1 fact(n) = n * fact(n-1) Example:factorial ;;; recursive Scheme implementation (define fact (lambda (n) (if (= n 0) 1 (* n (fact (- n 1))) ))) ;;; not tail recursive: after recursive call, must multiply by n
fact(0) = 1 fact(n) = n * fact(n-1) Example:factorial ;;; tail recursive implementation (define tr_fact (lambda (n acc) (if (= n 0) acc (fact (- n 1) (* n acc)) ))) ;;; tail recursive: (* n acc) done before recursive call!
Hiding helper ;;; tail recursive implementation (define fact (letrec ((helper (lambda (n acc) (if (= n 0) acc (fact (- n 1) (* n acc)) ))) (helper n 1) ))