# Perl | Tail Calls in Function Recursion

Recursion in Perl is any function that does not uses the `for` loop or the `while` loop, instead calls itself during the execution of the program and the corresponding function is known as recursive function.

Tail recursive function is a special case of recursion in which the function call statement is performed as the final action of the procedure. So `return loop(..);` would work, but `return loop() + operation;` would not. Tail recursion (or tail-end recursion) is particularly useful, and often easy to handle in implementations. The implementation of tail-recursion is mainly done to avoid the space occupied by stack data structure which keeps track of the data returned from the previous recursion call statement.

Following are few examples for a better understanding of the concept:

Examples 1:

 `#!/usr/bin/perl  ` ` `  `# Perl Program to calculate Factorial  ` ` `  `# Recursion without tail call ` `sub` `recurse_fact  ` `{  ` `    ``my` `\$x` `= ``\$_``;  ` ` `  `    ``# checking if that value is 0 or 1  ` `    ``if` `(``\$x` `== 0 || ``\$x` `== 1)  ` `    ``{  ` `        ``return` `1;  ` `    ``}  ` `     `  `    ``# Recursively calling function with  ` `    ``# the next value which is one less ` `    ``# than current one  ` `    ``else` `    ``{  ` `        ``return` `\$x` `* recurse_fact(``\$x` `- 1);  ` `    ``}  ` `}  ` ` `  `# Recursion using Tail Call ` `sub` `tail_recurse_fact  ` `{  ` `    ``my` `(``\$ans``, ``\$x``) = ``@_``;  ` `     `  `    ``# checking if that value is 0 or 1  ` `    ``if` `(``\$x` `== 0 || ``\$x` `== 1)  ` `    ``{  ` `        ``return` `\$ans``;  ` `    ``}  ` `     `  `    ``# Recursively calling function with  ` `    ``# the next value which is one less ` `    ``# than current one  ` `    ``else` `    ``{  ` `        ``return` `tail_recurse_fact(``\$ans` `* ``\$x``, ``\$x` `- 1);  ` `    ``}  ` `}  ` ` `  `# Driver Code  ` `\$a` `= 5;  ` ` `  `# Function call and printing result after return  ` `print` `"Factorial of a number \$a "``,  ` `          ``"through recursion is "``, recurse_fact(``\$a``); ` `           `  `print` `"\nFactorial of a number \$a "``,  ` `       ``"through tail-recursion is "``,  ` `           ``tail_recurse_fact(1, ``\$a``);  `

Output:

```Factorial of a number 5 through recursion is 120
Factorial of a number 5 through tail-recursion is 120
```

In the non-tail version, the compiler needs to keep track of the number you’re going to multiply it with, whereas in the tail-call version the compiler can realize that the only work left to do is another function call and it can forget about all of the variables and states used in the current function.

Examples 2:

 `#!/usr/bin/perl ` ` `  `# Perl program to demonstrate the ` `# use of tail-recursion ` `use` `strict; ` `use` `warnings; ` ` `  `sub` `recurse_fib ` `{ ` `    ``my` `\$n` `= ``shift``; ` ` `  `    ``if` `(``\$n` `== 1 or ``\$n` `== 2)  ` `    ``{ ` `        ``return` `1  ` `    ``} ` `     `  `    ``# recursive calling ` `    ``return` `(recurse_fib(``\$n` `- 1) +  ` `            ``recurse_fib(``\$n` `- 2));          ` `} ` ` `  `sub` `tail_recurse_fib  ` `{ ` `    ``my` `(``\$n``, ``\$a``, ``\$b``) = ``@_``; ` ` `  `    ``if` `(``\$n` `== 1)  ` `    ``{ ` `        ``return` `\$a` `    ``} ` `    ``if` `(``\$n` `== 2)  ` `    ``{ ` `        ``return` `\$b` `    ``} ` `    ``else`  `    ``{ ` `        ``# tail recursive calling ` `        ``return` `tail_recurse_fib(``\$n` `- 1, ``\$b``, ``\$a` `+ ``\$b``)          ` `    ``}          ` `} ` ` `  `# Driver code ` `\$a` `= 10; ` `print` `"Fibonacci upto \$a through recursion is "``,  ` `                                ``recurse_fib(``\$a``); ` `print` `"\nFibonacci upto \$a through tail-recursion is "``,  ` `                            ``tail_recurse_fib(``\$a``, 1, 1);  `

Output:

```Fibonacci upto 10 through recursion is 55
Fibonacci upto 10 through tail-recursion is 55
```

Use of `goto` statement to demonstrate Tail Recursion: `goto` will transfer the compiler to the subroutine of the given name from the currently running subroutine. This will replace the function call and creates a recursion process in the same way.

 `# Perl program to demonstrate the ` `# use of tail-recursion ` `use` `warnings; ` ` `  `sub` `recurse ` `{ ` `    ``my` `\$i` `= ``shift``; ` `    ``return` `if` `\$i` `== 0; ` `    ``recurse(``\$i` `- 1); ` `} ` ` `  `sub` `tail_recurse  ` `{ ` `    ``my` `\$i` `= ``shift``; ` `    ``return` `if` `\$i` `== 0; ` `    ``@_` `= (``\$i` `- 1); ` `    ``goto` `&tail_recurse; ` `} ` ` `  `# Driver Code ` `print` `"recursing\n"``; ` `recurse(200); ` ` `  `print` `"tail_recursing\n"``; ` `tail_recurse(200); `

Output:

```recursing
tail_recursing
```

In the above example the `recurse` function will produce a fatal error of ‘deep recursion’ while the `tail_recurse` will work fine.

### Elimination of Tail Call

Tail recursive is better than non-tail recursive as tail-recursive can be optimized by modern compilers. What a modern compiler do to optimize the tail recursive code is known as tail call elimination. Tail call elimination saves stack space. It replaces a function call with a goto statement. This really isn’t elimination – it is an optimization.

Sometimes a deeply recursive method is the easiest solution to a problem, but if you recurse more than a couple of hundred calls you’ll hit Perl’s “deep recursion” error. That is the reason why tail-recursive is used over non-tail recursive codes in Perl.

If we take a closer look at the above-discussed function, we can remove the last call with goto. Below are examples of tail call elimination.

Examples 1: Factorial of a number

 `#!/usr/bin/perl  ` ` `  `# Perl Program to calculate Factorial  ` `sub` `tail_recurse_fact  ` `{  ` `    ``my` `\$ans` `= ``shift``;  ` `    ``my` `\$x` `= ``shift``;  ` `     `  `    ``# checking if that value is 0 or 1  ` `    ``if` `(``\$x` `== 0 || ``\$x` `== 1)  ` `    ``{  ` `        ``return` `\$ans``;  ` `    ``}  ` `     `  `    ``# Recursively calling function with  ` `    ``# the next value which is one less  ` `    ``# than current one  ` `    ``else` `    ``{  ` `        ``@_` `= (``\$x` `* ``\$ans``, ``\$x` `- 1); ` `        ``goto` `&tail_recurse_fact;  ` `    ``}  ` `}  ` ` `  `# Driver Code  ` `\$a` `= 5;  ` ` `  `# Function call and printing result after return ` `print` `"Factorial of a number \$a "``,  ` `     ``"through tail-recursion is "``,  ` `         ``tail_recurse_fact(1, ``\$a``);  `

Output:

```Factorial of a number 5 through tail-recursion is 120
```

Examples 2: Fibonacci upto n

 `#!/usr/bin/perl ` ` `  `# Perl program to demonstrate the ` `# use of tail-recursion-elimination ` `use` `strict; ` `use` `warnings; ` ` `  `sub` `tail_recurse_fib ` `{ ` `    ``my` `\$n` `= ``shift``; ` `    ``my` `\$a` `= ``shift``; ` `    ``my` `\$b` `= ``shift``; ` ` `  `    ``if` `(``\$n` `== 1)  ` `    ``{ ` `        ``return` `\$a` `    ``} ` `    ``if` `(``\$n` `== 2)  ` `    ``{ ` `        ``return` `\$b` `    ``} ` `    ``else`  `    ``{ ` `        ``@_` `= (``\$n` `- 1, ``\$b``, ``\$a` `+ ``\$b``); ` `         `  `        ``# tail recursive calling ` `        ``goto` `&tail_recurse_fib;         ` `    ``}          ` `} ` ` `  `# Driver code ` `\$a` `= 10; ` `print` `"Fibonacci upto \$a through tail-recursion is "``, ` `                          ``tail_recurse_fib(``\$a``, 1, 1);  `

Output:

```Fibonacci upto 10 through recursion is 55
Fibonacci upto 10 through tail-recursion is 55
```

My Personal Notes arrow_drop_up Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.

Article Tags :
Practice Tags :

Be the First to upvote.

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.