Recursion and Iteration Let the entertainment begin - PowerPoint PPT Presentation

1 / 57
About This Presentation
Title:

Recursion and Iteration Let the entertainment begin

Description:

(letrec ((countdown (lambda (i) (if (= i 0) 'liftoff (begin (display i) (newline) ... (countdown (- i 1) Recursion and Iteration. 32. Recursion and Stack Frames ... – PowerPoint PPT presentation

Number of Views:97
Avg rating:3.0/5.0
Slides: 58
Provided by: Michael1759
Category:

less

Transcript and Presenter's Notes

Title: Recursion and Iteration Let the entertainment begin


1
Recursion and IterationLet the entertainment
begin
CS 480/680 Comparative Languages
2
No Iteration??
  • Yes, its true, there is no iteration in Scheme.
    So, how do we achieve simple looping constructs?
    Heres a simple example from Cal-Tech

3
Summing integers
  • How do I compute the sum of the first N integers?

4
Decomposing the sum
  • Sum of first N integers
  • N N-1 N-2 1
  • N ( N-1 N-2 1 )
  • N sum of first N-1 integers

5
to Scheme
  • Sum of first N integers
  • N sum of first N-1 integers
  • Convert to Scheme (first attempt)
  • (define (sum-integers n)
  • ( n (sum-integers (- n 1))))

6
Recursion in Scheme
  • (define (sum-integers n)
  • ( n (sum-integers (- n 1))))
  • sum-integers defined in terms of itself
  • This is a recursively defined procedure
  • ... which is incorrect
  • Can you spot the error?

7
Almost
  • Whats wrong?
  • (define (sum-integers n)
  • ( n (sum-integers (- n 1))))
  • Gives us

N N-1 1 0 -1 -2
8
Debugging
  • Fixing the problem
  • it doesnt stop at zero!
  • Revised
  • (define (sum-integers n)
  • (if ( n 0)
  • 0
  • ( n (sum-integers (- n 1)))))
  • How does this evaluate?

9
Warning
  • The substitution evaluation you are about to see
    is methodical, mechanistic,
  • and extremely tedious.
  • It will not all fit on one slide.
  • Don't take notes, but instead try to grasp the
    overall theme of the evaluation.

10
Evaluating
  • Evaluate (sum-integers 3)
  • evaluate 3 ? 3
  • evaluate sum-integers ? (lambda (n) (if ))
  • apply (lambda (n)
  • (if ( n 0)
  • 0
  • ( n (sum-integers (- n
    1))))) to 3
  • ? (if ( 3 0) 0 ( 3 (sum-integers (- 3 1))))

11
Evaluating
  • Evaluate (if ( 3 0) 0 ( 3 (sum-integers (- 3
    1))))
  • evaluate ( 3 0)
  • evaluate 3 ? 3
  • evaluate 0 ? 0
  • evaluate ?
  • apply to 3, 0 ? f
  • since expression is false,
  • replace with false clause
  • ( 3 (sum-integers (- 3 1)))
  • evaluate ( 3 (sum-integers (- 3 1)))

12
Evaluating
  • evaluate ( 3 (sum-integers (- 3 1)))
  • evaluate 3 ? 3
  • evaluate (sum-integers (- 3 1))
  • evaluate (- 3 1) ...skip steps ? 2
  • evaluate sum-integers?(lambda (n) (if ))

13
Evaluating
  • evaluate ( 3 (sum-integers (- 3 1)))
  • evaluate 3 ? 3
  • evaluate (sum-integers (- 3 1))
  • evaluate (- 3 1) ...skip steps ? 2
  • evaluate sum-integers?(lambda (n) (if ))

Note now pending ( 3 )
14
Evaluating
Pending ( 3 )
  • apply (lambda (n)
  • (if ( n 0)
  • 0
  • ( n (sum-integers (- n 1)))))
    to 2
  • ? (if ( 2 0) 0 ( 2 (sum-integers (- 2 1)))

15
Evaluating
Pending ( 3 )
  • evaluate (if ( 2 0) 0 ( 2 (sum-integers (- 2
    1)))
  • evaluate ( 2 0) skip steps ? f
  • since expression is false,
  • replace with false clause
  • ( 2 (sum-integers (- 2 1)))
  • evaluate ( 2 (sum-integers (- 2 1)))

16
Evaluating
Pending ( 3 )
  • evaluate ( 2 (sum-integers (- 2 1)))
  • evaluate 2 ? 2
  • evaluate (sum-integers (- 2 1))
  • evaluate (- 2 1) ...skip steps ? 1
  • evaluate sum-integers?(lambda (n) (if ))
  • apply (lambda (n) ) to 1
  • (if ( 1 0) 0 ( 1 (sum-integers (- 1 1))))
  • evaluate ( 1 0) ...skip steps ? f

Note pending ( 3 ( 2 ))
17
Evaluating
Pending ( 3 ( 2 ))
  • Evaluate ( 1 (sum-integers (- 1 1)))
  • evaluate 1 ? 1
  • evaluate (sum-integers (- 1 1))
  • evaluate (- 1 1) ...skip steps ? 0
  • evaluate sum-integers?(lambda (n) (if ))
  • apply (lambda (n) ) to 0
  • (if ( 0 0) 0 ( 1 (sum-integers (- 0 1))))
  • evaluate ( 0 0) ? t
  • result 0

Note pending ( 3 ( 2 ( 1 0)))
18
Evaluating
Pending ( 3 ( 2 ( 1 0)))
  • Back to pending
  • Know (sum-integers (- 1 1)) ? 0 prev slide
  • Evaluate ( 1 (sum-integers (- 1 1)))
  • evaluate 1 ? 1
  • evaluate (sum-integers (- 1 1)) ? 0
  • evaluate ?
  • apply to 1, 0 ? 1

Note pending ( 3 ( 2 1))
19
Evaluating
Pending ( 3 ( 2 1))
  • Back to pending
  • Know (sum-integers (- 2 1)) ? 1 prev slide
  • Evaluate ( 2 (sum-integers (- 2 1)))
  • evaluate 2 ? 2
  • evaluate (sum-integer (- 2 1)) ? 1
  • evaluate ?
  • apply to 2, 1 ? 3

Note pending ( 3 3)
20
Evaluating
  • Finish pending
  • ( 3 3)
  • final result 6

21
Yeah!!!
  • Substitution model
  • works fine for recursion.
  • Recursive calls are well-defined.
  • Careful application of model shows us what they
    mean and how they work.

22
Recursive Functions
  • Since there are no iterative constructs in
    Scheme, most of the power comes from writing
    recursive functions
  • This is fairly straightforward if you want the
    procedure to be global

(define factorial (lambda (n) (if ( n 0)
1 ( n (factorial (- n 1)))))) (factorial
5) 120
23
The trick
  • Must find the structure of the problem
  • How can I break it down into sub-problems?
  • What are the base cases?

24
List Processing
  • Suppose I want to search a list for the max
    value?
  • A standard list
  • What is the base case?
  • What state do I need to maintain?

lst
3
7
4
1
25
More list processing
  • How about a list of X-Y pairs?
  • What would the list look like?
  • Given X, find Y
  • Base case
  • State
  • Helper procedures?

26
Using Recursion
  • Write avg.scheme
  • See list-position.scheme
  • See count_atoms.scheme
  • See printtype.scheme

27
Mutual Recursion
(define is-even? (lambda (n) (if ( n 0)
t (is-odd? (- n 1))))) (define is-odd?
(lambda (n) (if ( n 0) f (is-even?
(- n 1)))))
  • Note Scheme has built-in primitives even? and
    odd?

28
Recursion and Local Definitions
  • Recursion gets more difficult when you want the
    functions to be local in scope

local-odd? is not yet defined
(let ((local-even? (lambda (n)
(if ( n 0) t
(local-odd? (- n 1))))) (local-odd? (lambda
(n) (if ( n 0) f
(local-even? (- n 1)))))) (list
(local-even? 23) (local-odd? 23)))
Can we fix this with let ?
29
letrec
  • letrec the variables introduced by letrec are
    available in both the body and the
    initializations
  • Custom made for local recursive definitions

(letrec ((local-even? (lambda (n)
(if ( n 0) t
(local-odd? (- n 1))))) (local-odd?
(lambda (n) (if ( n 0)
f (local-even? (- n
1)))))) (list (local-even? 23) (local-odd? 23)))
30
Recursion for loops
(letrec ((countdown (lambda (i)
(if ( i 0) 'liftoff
(begin (display i)
(newline)
(countdown (- i 1)))))))
(countdown 10))
  • Instead of a for loop, this letrec uses a
    recursive procedure on the variable i, which
    starts at 10 in the procedure call.

31
Named let
((let countdown ((i 10)) (if ( i 0) 'liftoff
(begin (display i) (newline)
(countdown (- i 1)))))
  • This is the same as the previous definition, but
    written more compactly
  • Named let is useful for defining and running loops

32
Recursion and Stack Frames
  • What happens when we call a recursive function?
  • Consider the following Fibonacci function

int fib(int N) int prev, pprev if (N
1) return 0 else if (N 2)
return 1 else prev fib(N-1)
pprev fib(N-2) return prev pprev
33
Stack Frames
  • Each call to Fib produces a new stack frame
  • 1000 recursive calls 1000 stack frames!
  • Inefficient relative to a for loop

pprev
prev
N
pprev
prev
N
34
  • How can we fix this inefficiency?
  • Heres an answer from the Cal-Tech slides

35
Example
  • Recall from last time
  • (define (sum-integers n)
  • (if ( n 0)
  • 0
  • ( n (sum-integers (- n 1)))))

36
Revisited (summarizing steps)
  • Evaluate (sum-integers 3)
  • (if ( 3 0) 0 ( 3 (sum-integers (- 3 1))))
  • (if f 0 ( 3 (sum-integers (- 3 1))))
  • ( 3 (sum-integers (- 3 1)))
  • ( 3 (sum-integers 2))
  • ( 3 (if ( 2 0) 0 ( 2 (sum-integers (- 2 1)))))
  • ( 3 ( 2 (sum-integers 1)))
  • ( 3 ( 2 (if ( 1 0) 0 ( 1 (sum-integer (- 1
    1))))))

37
Revisited (summarizing steps)
  • ( 3 ( 2 ( 1 (sum-integers 0))))
  • ( 3 ( 2 ( 1 (if ( 0 0) 0 ))))
  • ( 3 ( 2 ( 1 (if t 0 ))))
  • ( 3 ( 2 ( 1 0)))
  • 6

38
Evolution of computation
  • (sum-integers 3)
  • ( 3 (sum-integers 2))
  • ( 3 ( 2 (sum-integers 1)))
  • ( 3 ( 2 ( 1 (sum-integers 0))))
  • ( 3 ( 2 ( 1 0)))

39
What can we say about the computation?
  • On input N
  • How many calls to sum-integers?
  • N1
  • How much work per call?
  • (sum-integers 3)
  • ( 3 (sum-integers 2))
  • ( 3 ( 2 (sum-integers 1)))
  • ( 3 ( 2 ( 1 (sum-integers 0))))
  • ( 3 ( 2 ( 1 0)))

40
Linear recursive processes
  • This is what we call a linear recursive process
  • Makes linear of calls
  • i.e. proportional to N
  • Keeps a chain of deferred operations linear in
    size w.r.t. input
  • i.e. proportional to N
  • (sum-integers 3)
  • ( 3 (sum-integers 2))
  • ( 3 ( 2 (sum-integers 1)))
  • ( 3 ( 2 ( 1 (sum-integers 0))))
  • ( 3 ( 2 ( 1 0)))
  • time C1 NC2

41
Another strategy
  • To sum integers
  • add up as we go along
  • 1 2 3 4 5 6 7
  • 1 12 123 1234 ...
  • 1 3 6 10 15 21 28

42
Alternate definition
  • (define (sum-int n)
  • (sum-iter 0 n 0)) start at 0, sum
    is 0
  • (define (sum-iter current max sum)
  • (if (gt current max)
  • sum
  • (sum-iter ( 1 current)
  • max
  • ( current sum))))

43
Evaluation of sum-int
  • (sum-int 3)
  • (sum-iter 0 3 0)
  • (define (sum-int n)
  • (sum-iter 0 n 0))
  • (define (sum-iter current
  • max
  • sum)
  • (if (gt current max) sum
  • (sum-iter ( 1 current)
  • max
  • ( current
  • sum))))

44
Evaluation of sum-int
  • (sum-int 3)
  • (sum-iter 0 3 0)
  • (if (gt 0 3) )
  • (sum-iter 1 3 0)
  • (define (sum-int n)
  • (sum-iter 0 n 0))
  • (define (sum-iter current
  • max
  • sum)
  • (if (gt current max) sum
  • (sum-iter ( 1 current)
  • max
  • ( current
  • sum))))

45
Evaluation of sum-int
  • (sum-int 3)
  • (sum-iter 0 3 0)
  • (if (gt 0 3) )
  • (sum-iter 1 3 0)
  • (if (gt 1 3) )
  • (sum-iter 2 3 1)
  • (define (sum-int n)
  • (sum-iter 0 n 0))
  • (define (sum-iter current
  • max
  • sum)
  • (if (gt current max) sum
  • (sum-iter ( 1 current)
  • max
  • ( current
  • sum))))

46
Evaluation of sum-int
  • (sum-int 3)
  • (sum-iter 0 3 0)
  • (if (gt 0 3) )
  • (sum-iter 1 3 0)
  • (if (gt 1 3) )
  • (sum-iter 2 3 1)
  • (if (gt 2 3) )
  • (sum-iter 3 3 3)
  • (define (sum-int n)
  • (sum-iter 0 n 0))
  • (define (sum-iter current
  • max
  • sum)
  • (if (gt current max) sum
  • (sum-iter ( 1 current)
  • max
  • ( current
  • sum))))

47
Evaluation of sum-int
  • (sum-int 3)
  • (sum-iter 0 3 0)
  • (if (gt 0 3) )
  • (sum-iter 1 3 0)
  • (if (gt 1 3) )
  • (sum-iter 2 3 1)
  • (if (gt 2 3) )
  • (sum-iter 3 3 3)
  • (if (gt 3 3) )
  • (sum-iter 4 3 6)
  • (define (sum-int n)
  • (sum-iter 0 n 0))
  • (define (sum-iter current
  • max
  • sum)
  • (if (gt current max) sum
  • (sum-iter ( 1 current)
  • max
  • ( current
  • sum))))

48
Evaluation of sum-int
  • (sum-int 3)
  • (sum-iter 0 3 0)
  • (if (gt 0 3) )
  • (sum-iter 1 3 0)
  • (if (gt 1 3) )
  • (sum-iter 2 3 1)
  • (if (gt 2 3) )
  • (sum-iter 3 3 3)
  • (if (gt 3 3) )
  • (sum-iter 4 3 6)
  • (if (gt 4 3) )
  • 6
  • (define (sum-int n)
  • (sum-iter 0 n 0))
  • (define (sum-iter current
  • max
  • sum)
  • (if (gt current max) sum
  • (sum-iter ( 1 current)
  • max
  • ( current
  • sum))))

49
What can we say about the computation?
  • on input N
  • How many calls to sum-iter?
  • N2
  • How much work per call?
  • (sum-int 3)
  • (sum-iter 0 3 0)
  • (sum-iter 1 3 0)
  • (sum-iter 2 3 1)
  • (sum-iter 3 3 3)
  • (sum-iter 4 3 6)
  • 6

50
What can we say about the computation?
  • on input N
  • How many calls to sum-iter?
  • N2
  • How much work per call?
  • constant
  • one comparison, one if, two additions, one call
  • How many deferred operations?
  • none
  • (sum-int 3)
  • (sum-iter 0 3 0)
  • (sum-iter 1 3 0)
  • (sum-iter 2 3 1)
  • (sum-iter 3 3 3)
  • (sum-iter 4 3 6)
  • 6

51
Whats different about these computations?
New
Old
(sum-int 3) (sum-iter 0 3 0) (sum-iter 1 3
0) (sum-iter 2 3 1) (sum-iter 3 3 3) (sum-iter 4
3 6)
  • (sum-integers 3)
  • ( 3 (sum-integers 2))
  • ( 3 ( 2 (sum-integers 1)))
  • ( 3 ( 2 ( 1 (sum-integers 0))))
  • ( 3 ( 2 ( 1 0)))

52
Linear iterative processes
  • This is what we call a linear iterative process
  • Makes linear calls
  • State of computation kept in a constant of
    state variables
  • state does not grow with problem size
  • requires a constant amount of storage space
  • (sum-int 3)
  • (sum-iter 0 3 0)
  • (sum-iter 1 3 0)
  • (sum-iter 2 3 1)
  • (sum-iter 3 3 3)
  • (sum-iter 4 3 6)
  • 6
  • time C1 NC2

53
Linear recursive vs linear iterative
  • Both require computational time which is linear
    in size of input
  • L.R. process requires space that is also linear
    in size of input
  • why?
  • L.I. process requires constant space
  • not proportional to size of input
  • more space-efficient than L.R. process

54
Linear recursive vs linear iterative
  • Why not always use linear iterative instead of
    linear recursive algorithm?
  • often the case in practice
  • Recursive algorithm sometimes much easier to
    write
  • and to prove correct
  • Sometimes space efficiency not the limiting factor

55
Tail-call elimination
((let countdown ((i 10)) (if ( i 0) 'liftoff
(begin (display i) (newline)
(countdown (- i 1)))))
  • Countdown uses only tail-recursion
  • Each call to countdown either does not call
    itself again, or does it as the very last thing
    done
  • Scheme recognizes tail recursion and converts it
    to an iterative (loop) construct internally

56
Mapping a procedure across a list
(map add2 '(1 2 3)) (3 4 5) (map cons '(1 2 3)
'(10 20 30)) ((1 . 10) (2 . 20) (3 . 30)) (map
'(1 2 3) '(10 20 30)) (11 22 33)
57
Exercises
  • Include error checking into avg.scheme
  • Divide by zero error
  • Non-numeric list items
  • Write a scheme function that accepts a single
    numeric argument and returns all numbers less
    than 10 that the argument is divisible by
  • Factor.scheme described in class
  • Write a scheme function that returns the first n
    Fibonacci numbers as a list (n is an argument)
Write a Comment
User Comments (0)
About PowerShow.com