Tail call, tail recursion and non tail recursion


Some concepts of tail call, tail recursion and non tail recursion and whether non tail recursion can be converted into tail recursion.

1、 Tail call:

Tail call refers to the last statement of a function. It is also a statement that returns the calling function. In other words, the return is a function. This function can be another function or its own function.

def fun_b(x):
  x = x -1
  return x

def function_a(x):
  x = x + 1
  return fun_ B (x) ා the most returned is a function

2、Tail recursion:

When a function calls itself when it returns, this situation is called tail recursion. It can’t have any other additional functions except the calling itself. Tail recursion is a special form of recursion, and it is also a special form of tail calling. Tail calls are not necessarily tail recursion.

Tail recursion features:

  1. In the regression process, the compiler will automatically generate optimized code without any operation. (the compiler finds that the use of stack space and the overhead of stack allocation and release can be reduced by covering the current stack instead of creating a new stack during the regression call.)
  2. Tail recursion is to pass changed parameters to the variables of recursive functions. When recursion occurs, the outer function passes the calculation result as a parameter to the memory function.
  3. The optimization of tail recursion is easy to understand from the assembly implementation of function calls. As long as no extra parameters are involved (that is, no extra stack capacity is needed, the top of the stack does not need to be expanded down and then called back to the function), the value of% EDI% ESI can be changed directly, and the function can be called again, that is to say, no extra like variables are needed.
def fun_b(x):
  if x == 1:
    return x
    return fun_ B (x) ා the last return calls its own function, which is tail recursion. If it is written as' return fun '_ B (x) + 1 'is not tail recursion

3、Non tail recursion:

Other recursive calls other than tail recursion are reduced to non tail recursion

4. The difference between stack calls

Ordinary recursive functions call many times, and the recursion level is very deep. The stack space is 0 (n), and the stack space can be o (1) after tail recursive optimization. The following is an example to observe the difference in stack occupancy:

#This is a non tail recursion
def normal_sum(x):
  if x == 1:
    return x
    return x + normal_sum(x - 1)

Call fun_ Sum (5) stack change of non tail recursion

5 + normal_sum(4)
5 + (4 + normal_sum(3))
5 + (4 + (3 + normal_sum(2)))
5 + (4 + (3 + (2 + normal_sum(1))))
5 + (4 + (3 + (2 + 1)))
5 + (4 + (3 + 3))
5 + (4 + 6)
5 + 10

Modify the above function to tail recursion (tail recursion is to pass the variable of the recursive function with the changed parameters)

def tail_sum(x, total=0):
  if x == 0:
    return total
    return tail_sum(x - 1, total + x)

The stack change of tail recursive tailrecsum (5,0) is as follows:

tail_sum(5, 0)
tail_sum(4, 5)
tail_sum(3, 9)
tail_sum(2, 12)
tail_sum(1, 14)
tail_sum(0, 15)

4. Can non tail recursion be converted back to tail recursion

adoptCPSTransform, can convert non tail recursion into tail recursion. Its core idea is to
It can be referred toThis blog

Lifelong learning!