Лучший способ для меня понять tail call recursion
- это особый случай рекурсии, когда последний вызов (или хвостовой вызов) - это сама функция.
Сравнение примеров, представленных в Python:
def recsum(x):
if x == 1:
return x
else:
return x + recsum(x - 1)
^ RECURSION
def tailrecsum(x, running_total=0):
if x == 0:
return running_total
else:
return tailrecsum(x - 1, running_total + x)
^ РЕАКЦИЯ ХВОСТА
Как вы можете видеть в общей рекурсивной версии, последний вызов в блоке кода - x + recsum(x - 1)
. Таким образом, после вызова метода recsum
, есть другая операция, которая x + ..
.
Однако в хвостовой рекурсивной версии последний вызов (или хвостовой вызов) в блоке кода равен tailrecsum(x - 1, running_total + x)
, что означает, что последний вызов был выполнен для самого метода, и после этого операции не выполнялось.
Этот момент важен, потому что хвостовая рекурсия, как видно здесь, не заставляет память расти, потому что, когда базовая виртуальная машина видит функцию, вызывающую себя в хвостовой позиции (последнее выражение, которое должно быть оценено в функции), она удаляет текущий стек кадр, который называется оптимизацией Tail Call (TCO).
EDIT
NB. Помните, что приведенный выше пример написан на языке Python, среда выполнения которого не поддерживает TCO. Это всего лишь пример, чтобы объяснить суть. TCO поддерживается на таких языках, как Scheme, Haskell и т. Д.