Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same...

29
Tail recursion in C

Transcript of Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same...

Page 1: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Tail recursion in C

Page 2: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Take this C code:

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

Page 3: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Stack

main()

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

Page 4: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Stack

main()always_zero(5)

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

Page 5: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Stack

main()always_zero(5)

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

Page 6: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Stack

main()always_zero(5)

always_zero(4)

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

Page 7: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Stack

always_zero(3)

main()always_zero(5)

always_zero(4)

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

Page 8: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Stack

always_zero(3)

main()always_zero(5)

always_zero(4)

always_zero(2)

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

Page 9: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Stack

always_zero(3)

main()always_zero(5)

always_zero(4)

always_zero(2)always_zero(1)

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

Page 10: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Stack

always_zero(3)

main()always_zero(5)

always_zero(4)

always_zero(2)

always_zero(0)

always_zero(1)

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

Page 11: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Stack

always_zero(3)

main()always_zero(5)

always_zero(4)

always_zero(2)always_zero(1)

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

0

Page 12: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Stack

always_zero(3)

main()always_zero(5)

always_zero(4)

always_zero(2)

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

0

Page 13: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Stack

always_zero(3)

main()always_zero(5)

always_zero(4)

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

0

Page 14: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Stack

main()always_zero(5)

always_zero(4)

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

0

Page 15: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Stack

main()always_zero(5)

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

0

Page 16: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Stack

main()

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

0

Page 17: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

A lot of unnecessary work and storage! Can we do better?

Page 18: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Tail recursion

main()always_zero(5)

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

Page 19: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Tail recursion

main()always_zero(4)

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

always_zero(5)

Page 20: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Tail recursion

main()always_zero(3)

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

always_zero(4)

Page 21: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Tail recursion

main()always_zero(2)

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

always_zero(3)

Page 22: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Tail recursion

main()always_zero(1)

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

always_zero(2)

Page 23: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Tail recursion

main()always_zero(0)

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

always_zero(1)

Page 24: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Tail recursion

main()

int always_zero(i){

if(i==0)return 0;

return always_zero(i-1);}

void main(){

always_zero(5);}

0

Page 25: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Tail recursion

● Just discard unnecessary functions from the stack

● Same results● O(1) space instead of O(n) space● Faster too!

● Can we do this for all recursive algorithms?

Page 26: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Take this C code:

int always_zero(i){

if(i==0)return 0;

return 5*always_zero(i-1);}

void main(){

always_zero(5);}

Page 27: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Can we do the same trick?

● No! Results returned by always_zero(0) need to be further processed by always_zero(1)

● Results from always_zero(0) cannot be returned directly to main()

● Need to pass through always_zero(1), always_zero(2), always_zero(3), ...

Page 28: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Tail recursion only works when we need no further processing.

Page 29: Tail recursion in C - MITweb.mit.edu/pmitros/www/ceti/tail-recursion-in-c.pdfCan we do the same trick? No! Results returned by always_zero(0) need to be further processed by always_zero(1)

Terminology

Scheme

Cfor(i=0; i<100; i++) {}

int f(int i){ if(i==0) return 0; return f(i-1);}

int f(int i){ if(i==0) return 1; else return i*f(i);}

Iteration Recursion

Iteration Normal recursionTail recursion