Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Термальное условие
Думаю, очевидно, что итеративный процесс потребляет меньше памяти.
Да, TCO делает это утверждение бессмысленным, если не ошибочным. В языках с TCO можно не задумываясь считать факториалы миллионов и (если есть нативная поддержка целых чисел любой длмны) — даже напечатать ответ.
Я думал, первая буква дважды упомянутой аббревиатуры TCO как бы намекает на это :)
После первых трех шишек, любая рекурсия автоматически выходит из под пера хвостовой.
const factorial = (n) => {
const iter = (counter, acc) => {
if (counter === 1) {
return acc;
}
return iter(counter - 1, counter * acc);
};
return iter(n, 1);
};const factorial = (n) => {
if (n === 0) {
return 1;
}
return n * factorial(n - 1);
}В JS нет TCO, так что код выше помрет на сто-с-чем-то итерации от переполнения стека.
Если вы думаете, что Фибоначчи не выразить через хвостовую рекурсию, то это не так.
defmodule Fib do
def calc(count), do: calc(1, 1, count - 1)
def calc(_p, acc, 0), do: acc
def calc(p, acc, count), do: calc(acc, acc + p, count - 1)
def test do
Enum.map(1..20, &calc/1)
end
end
#⇒ [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,
# 377, 610, 987, 1597, 2584, 4181, 6765, 10946]Elixir поддерживает TCO, поэтому:
1_000_000 |> Fib.calc() |> to_string() |> String.length()
#⇒ 208988
Функциональное программирование с точки зрения EcmaScript. Рекурсия и её виды