Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls...
Transcript of Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls...
![Page 1: Tail Recursion - pages.github-dev.cs.illinois.edu · Objectives AccumulatingRecursion TailCalls TailPosition Asubexpressionsofexpressionse,ifitisevaluated,will betakenasthevalueofe.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/1.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/2.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/3.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/4.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/5.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/6.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/7.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/8.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/9.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/10.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/11.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/12.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/13.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/14.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/15.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/16.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/17.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/18.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/19.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/20.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/21.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/22.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/23.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/24.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/25.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/26.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/27.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/28.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.](https://reader035.fdocuments.net/reader035/viewer/2022071003/5fc05e3f81affe3c881cc225/html5/thumbnails/29.jpg)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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.