tail recursion - pages.github-dev.cs.illinois.edu · objectives accumulatingrecursion tailcalls...

29
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Objectives Accumulating Recursion Tail Recursion Dr. Mattox Beckman University of Illinois at Urbana-Champaign Department of Computer Science

Upload: others

Post on 18-Aug-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

Tail Recursion

Dr. Mattox Beckman

University of Illinois at Urbana-ChampaignDepartment of Computer Science

Page 2: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

Objectives

▶ Understand what makes a function tail recursive.▶ Explain how the compiler makes tail recursion efficient.

Page 3: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

Tail Calls

Tail Position A subexpression s of expressions e, if it is evaluated, willbe taken as the value of e.

▶ if x > 3 then x + 2 else x - 4▶ f (x * 3)—no (proper) tail position here.

Tail Call A function call that occurs in tail position.▶ if h x then h x else x + g x

Page 4: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

Your Turn

Find the tail calls!

Example Code

1 calc n i | n==2 = i2 | odd n = calc (n*3+1) (i+1)3 | otherwise = calc (n `div` 2) (i+1)4

5 fib 0 = 06 fib 1 = 17 fib n = fib (n-1) + fib (n-2)

Page 5: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

Tail Call Example

▶ If one function calls another in tail position, we get a specialbehavior.

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

▶ What happens when we call foo 1?

Page 6: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

Tail Call Example

▶ If one function calls another in tail position, we get a specialbehavior.

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

▶ What happens when we call foo 1?

x 1

ret

Page 7: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

Tail Call Example

▶ If one function calls another in tail position, we get a specialbehavior.

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

▶ What happens when we call foo 1?

x 1

ret

y 2

ret

Page 8: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

Tail Call Example

▶ If one function calls another in tail position, we get a specialbehavior.

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

▶ What happens when we call foo 1?

x 1

ret

y 2

ret

z 3

ret

Page 9: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

Tail Call Example

▶ If one function calls another in tail position, we get a specialbehavior.

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

▶ What happens when we call foo 1?

x 1

ret

y 2

ret

z 3

ret 30

Page 10: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

Tail Call Example

▶ If one function calls another in tail position, we get a specialbehavior.

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

▶ What happens when we call foo 1?

x 1

ret

y 2

30

ret

z 3

ret 30

Page 11: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

Tail Call Example

▶ If one function calls another in tail position, we get a specialbehavior.

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

▶ What happens when we call foo 1?

x 1

ret

y 2

30

ret 30

z 3

ret 30

Page 12: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

Tail Call Example

▶ If one function calls another in tail position, we get a specialbehavior.

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

▶ What happens when we call foo 1?

x 1

30

ret

y 2

30

ret 30

z 3

ret 30

Page 13: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

Tail Call Example

▶ If one function calls another in tail position, we get a specialbehavior.

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

▶ What happens when we call foo 1?

x 1

30

ret 30

y 2

30

ret 30

z 3

ret 30

Page 14: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

The Tail Call Optimization

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

▶ If that’s the case, we can cut out the middle man...

Page 15: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

The Tail Call Optimization

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

▶ If that’s the case, we can cut out the middle man...

x 1

ret

Page 16: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

The Tail Call Optimization

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

▶ If that’s the case, we can cut out the middle man...

x 1

ret

y 2

ret

Page 17: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

The Tail Call Optimization

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

▶ If that’s the case, we can cut out the middle man...

x 1

ret

y 2

ret

z 3

ret

Page 18: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

The Tail Call Optimization

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

▶ If that’s the case, we can cut out the middle man...

x 1

ret

y 2

ret

z 3

ret 30

Page 19: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

The Tail Call Optimization

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

▶ If that’s the case, we can cut out the middle man...

x 1

30

ret 30

y 2

ret

z 3

ret 30

Page 20: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

The Tail Call Optimization

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

▶ If that’s the case, we can cut out the middle man...▶ Actually, we can do even better than that.

Page 21: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

The optimization

▶ When a function is in tail position, the compiler will recycle theactivation record!

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

Page 22: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

The optimization

▶ When a function is in tail position, the compiler will recycle theactivation record!

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

x 1

ret

Page 23: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

The optimization

▶ When a function is in tail position, the compiler will recycle theactivation record!

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

y 2

ret

Page 24: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

The optimization

▶ When a function is in tail position, the compiler will recycle theactivation record!

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

z 3

ret

Page 25: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

The optimization

▶ When a function is in tail position, the compiler will recycle theactivation record!

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

z 3

ret 30

Page 26: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

The optimization

▶ When a function is in tail position, the compiler will recycle theactivation record!

Example

1 foo x = bar (x+1)2 bar y = baz (y+1)3 baz z = z * 10

z 3

ret 30

▶ This allows recursive functions to be written as loops internally.

Page 27: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

Direct-Style Recursion

▶ In recursion, you split the input into the “first piece” and the “rest ofthe input”.

▶ In direct-style recursion: the recursive call computes the result forthe rest of the input, and then the function combines the result withthe first piece.

▶ In other words, you wait until the recursive call is done to generateyour result.

Direct Style Summation

1 sum [] = 02 sum (x:xs) = x + sum xs

Page 28: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

Accumulating Recursion

▶ In accumulating recursion: generate an intermediate result now, andgive that to the recursive call.

▶ Usually this requires an auxiliary function.

Tail Recursive Summation

1 sum xx = aux xx 02 where aux [] a = a3 aux (x:xs) a = aux xs (a+x)

Page 29: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Objectives Accumulating Recursion

Further Reading

▶ Forward recursion can be made to traverse a list at return timerather than call time, forming a pattern called “There and BackAgain,” which can do some interesting things….

▶ Example: write a function convolve which takes two lists(x1 x2 · · · xn) and (y1 y2 · · · yn) and produces anoutput list (x1yn x2yn−2 · · · xny1) where n is unknown. UseonlyO(n) recursive calls, and no temporary lists.

▶ For the solution, see Olivier Danvy’s paper There and Back Again.