57
Recursion and Iteration Recursion and Iteration Let the entertainment begin… Let the entertainment begin… 480/680 – Comparative Languages 480/680 – Comparative Languages

Recursion and Iteration Let the entertainment begin…

  • Upload
    nubia

  • View
    34

  • Download
    2

Embed Size (px)

DESCRIPTION

CS 480/680 – Comparative Languages. Recursion and Iteration Let the entertainment begin…. No Iteration??. Yes, it’s true, there is no iteration in Scheme. So, how do we achieve simple looping constructs? Here’s a simple example from Cal-Tech:. Summing integers. - PowerPoint PPT Presentation

Citation preview

Page 1: Recursion and Iteration Let the entertainment begin…

Recursion and IterationRecursion and IterationLet the entertainment begin…Let the entertainment begin…

CS 480/680 – Comparative LanguagesCS 480/680 – Comparative Languages

Page 2: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 2

No Iteration??No Iteration?? Yes, it’s true, there is no iteration in Scheme.

So, how do we achieve simple looping constructs? Here’s a simple example from Cal-Tech:

Page 3: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 3

Summing integersSumming integers How do I compute the sum of the first N

integers?

Page 4: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 4

Decomposing the sumDecomposing 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]

Page 5: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 5

to Schemeto 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))))

Page 6: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 6

Recursion in SchemeRecursion 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?

Page 7: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 7

Almost…Almost… What’s wrong?

(define (sum-integers n)

(+ n (sum-integers (- n 1))))

Gives us:

N + N-1 + …+ 1 + 0 + -1 + -2 + …

Page 8: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 8

DebuggingDebugging

Fixing the problem:• it doesn’t stop at zero!

Revised:

(define (sum-integers n)

(if (= n 0)

0

(+ n (sum-integers (- n 1))))) How does this evaluate?

Page 9: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 9

WarningWarning

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.

Page 10: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 10

EvaluatingEvaluating

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))))

Page 11: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 11

Evaluating…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)))

Page 12: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 12

Evaluating…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 …))

Page 13: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 13

Evaluating…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 …)

Page 14: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 14

Evaluating…Evaluating…

apply (lambda (n) (if (= n 0)

0

(+ n (sum-integers (- n 1))))) to 2

(if (= 2 0) 0 (+ 2 (sum-integers (- 2 1)))

Pending (+ 3 …)

Page 15: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 15

Evaluating…Evaluating…

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)))

Pending (+ 3 …)

Page 16: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 16

Evaluating…Evaluating…

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

Pending (+ 3 …)

Note: pending (+ 3 (+ 2 …))

Page 17: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 17

Evaluating…Evaluating…

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

Pending (+ 3 (+ 2 …))

Note: pending (+ 3 (+ 2 (+ 1 0)))

Page 18: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 18

EvaluatingEvaluating

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

Pending (+ 3 (+ 2 (+ 1 0)))

Note: pending (+ 3 (+ 2 1))

Page 19: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 19

EvaluatingEvaluating

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

Pending (+ 3 (+ 2 1))

Note: pending (+ 3 3)

Page 20: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 20

EvaluatingEvaluatingFinish pending: (+ 3 3) … final result: 6

Page 21: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 21

……Yeah!!! …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.

Page 22: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 22

Recursive FunctionsRecursive 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

Page 23: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 23

The trickThe trick Must find the structure of the problem:

• How can I break it down into sub-problems?• What are the base cases?

Page 24: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 24

List ProcessingList 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?

3 7 4 1

lst

Page 25: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 25

More list processingMore 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?

3 7 4 1

lst

5 2 3 9

Page 26: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 26

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

Page 27: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 27

Mutual RecursionMutual Recursion

Note: Scheme has built-in primitives even? and odd?

(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)))))

Page 28: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 28

Recursion and Local DefinitionsRecursion and Local Definitions Recursion gets more difficult when you want

the functions to be local in scope:

(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)))

local-odd? is not yet definedlocal-odd? is not yet defined

Can we fix this with let* ?Can we fix this with let* ?

Page 29: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 29

letrecletrec 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)))

Page 30: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 30

Recursion for loopsRecursion for loops

Instead of a for loop, this letrec uses a recursive procedure on the variable i, which starts at 10 in the procedure call.

(letrec ((countdown (lambda (i) (if (= i 0) 'liftoff (begin (display i) (newline) (countdown (- i 1))))))) (countdown 10))

Page 31: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 31

Named Named letlet

This is the same as the previous definition, but written more compactly

Named let is useful for defining and running loops

((let countdown ((i 10)) (if (= i 0) 'liftoff (begin (display i) (newline) (countdown (- i 1)))))

Page 32: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 32

Recursion and Stack FramesRecursion 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; }}

Page 33: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 33

Stack FramesStack Frames Each call to Fib

produces a new stack frame

1000 recursive calls = 1000 stack frames!

Inefficient relative to a for loop

Nprev pprev

Nprev pprev

Page 34: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 34

How can we fix this inefficiency?

Here’s an answer from the Cal-Tech slides:

Page 35: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 35

ExampleExample

Recall from last time:

(define (sum-integers n)

(if (= n 0)

0

(+ n (sum-integers (- n 1)))))

Page 36: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 36

Revisited (summarizing steps)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))))))

Page 37: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 37

Revisited (summarizing steps)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

Page 38: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 38

Evolution of computationEvolution of computation (sum-integers 3) (+ 3 (sum-integers 2)) (+ 3 (+ 2 (sum-integers 1))) (+ 3 (+ 2 (+ 1 (sum-integers 0)))) (+ 3 (+ 2 (+ 1 0)))

Page 39: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 39

What can we say about the What can we say about the computation?computation?

On input N: How many calls to sum-

integers?N+1

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)))

Page 40: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 40

Linear recursive processesLinear 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 + N*C2

Page 41: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 41

Another strategyAnother strategyTo sum integers…

add up as we go along: 1 2 3 4 5 6 7 … 1 1+2 1+2+3 1+2+3+4 ... 1 3 6 10 15 21 28 …

Page 42: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 42

Alternate definitionAlternate definition(define (sum-int n)

(sum-iter 0 n 0)) ;; start at 0, sum is 0

(define (sum-iter current max sum)

(if (> current max)

sum

(sum-iter (+ 1 current)

max

(+ current sum))))

Page 43: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 43

Evaluation of Evaluation of sum-intsum-int

(define (sum-int n)

(sum-iter 0 n 0))

(define (sum-iter current

max

sum)

(if (> current max) sum

(sum-iter (+ 1 current)

max

(+ current

sum))))

(sum-int 3) (sum-iter 0 3 0)

Page 44: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 44

Evaluation of Evaluation of sum-intsum-int

(define (sum-int n)

(sum-iter 0 n 0))

(define (sum-iter current

max

sum)

(if (> current max) sum

(sum-iter (+ 1 current)

max

(+ current

sum))))

(sum-int 3) (sum-iter 0 3 0) (if (> 0 3) … ) (sum-iter 1 3 0)

Page 45: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 45

Evaluation of Evaluation of sum-intsum-int

(define (sum-int n)

(sum-iter 0 n 0))

(define (sum-iter current

max

sum)

(if (> current max) sum

(sum-iter (+ 1 current)

max

(+ current

sum))))

(sum-int 3) (sum-iter 0 3 0) (if (> 0 3) … ) (sum-iter 1 3 0) (if (> 1 3) … ) (sum-iter 2 3 1)

Page 46: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 46

Evaluation of Evaluation of sum-intsum-int

(define (sum-int n)

(sum-iter 0 n 0))

(define (sum-iter current

max

sum)

(if (> current max) sum

(sum-iter (+ 1 current)

max

(+ current

sum))))

(sum-int 3) (sum-iter 0 3 0) (if (> 0 3) … ) (sum-iter 1 3 0) (if (> 1 3) … ) (sum-iter 2 3 1) (if (> 2 3) … ) (sum-iter 3 3 3)

Page 47: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 47

Evaluation of Evaluation of sum-intsum-int

(define (sum-int n)

(sum-iter 0 n 0))

(define (sum-iter current

max

sum)

(if (> current max) sum

(sum-iter (+ 1 current)

max

(+ current

sum))))

(sum-int 3) (sum-iter 0 3 0) (if (> 0 3) … ) (sum-iter 1 3 0) (if (> 1 3) … ) (sum-iter 2 3 1) (if (> 2 3) … ) (sum-iter 3 3 3) (if (> 3 3) … ) (sum-iter 4 3 6)

Page 48: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 48

Evaluation of Evaluation of sum-intsum-int

(define (sum-int n)

(sum-iter 0 n 0))

(define (sum-iter current

max

sum)

(if (> current max) sum

(sum-iter (+ 1 current)

max

(+ current

sum))))

(sum-int 3) (sum-iter 0 3 0) (if (> 0 3) … ) (sum-iter 1 3 0) (if (> 1 3) … ) (sum-iter 2 3 1) (if (> 2 3) … ) (sum-iter 3 3 3) (if (> 3 3) … ) (sum-iter 4 3 6) (if (> 4 3) … ) 6

Page 49: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 49

What can we say about the What can we say about the computation?computation?

on input N: How many calls to sum-

iter?N+2

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

Page 50: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 50

What can we say about the What can we say about the computation?computation?

on input N: How many calls to sum-

iter?N+2

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

Page 51: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 51

What’s different about these What’s different about these computations?computations?

(sum-integers 3)

(+ 3 (sum-integers 2))

(+ 3 (+ 2 (sum-integers 1)))

(+ 3 (+ 2 (+ 1 (sum-integers 0))))

(+ 3 (+ 2 (+ 1 0)))

(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)

Old New

Page 52: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 52

Linear iterative processesLinear 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 + N*C2

Page 53: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 53

Linear recursive vs linear iterativeLinear 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

Page 54: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 54

Linear recursive vs linear iterativeLinear 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

Page 55: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 55

Tail-call eliminationTail-call elimination

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

((let countdown ((i 10)) (if (= i 0) 'liftoff (begin (display i) (newline) (countdown (- i 1)))))

Page 56: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 56

Mapping a procedure across a listMapping 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)

Page 57: Recursion and Iteration Let the entertainment begin…

Recursion and Iteration 57

ExercisesExercises 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)