Что такое хвостовая рекурсия

Ответ

Хвостовая рекурсия — это частный случай рекурсии, когда рекурсивный вызов является последней операцией в функции. В этом случае стек вызовов не растёт, так как компилятор/интерпретатор может оптимизировать его в итерацию.

Пример (не хвостовая рекурсия):

function factorial(n) {
    if (n <= 1) return 1;
    return n * factorial(n - 1); // Умножение после вызова
}

Пример (хвостовая рекурсия):

function factorial(n, acc = 1) {
    if (n <= 1) return acc;
    return factorial(n - 1, n * acc); // Вызов — последняя операция
}

В ES6 хвостовая рекурсия поддерживается, но не во всех движках. Для гарантированной оптимизации лучше использовать циклы.

Ответ 18+ 🔞

А, ну это же про хвостовую рекурсию, классика жанра, блядь! Сидишь такой, пишешь код, думаешь — о, какая элегантная хуйня, как красиво функция сама себя вызывает. А потом бац — стек переполняется, и твоя программа накрывается медным тазом, ёпта!

Так вот, хвостовая рекурсия — это когда функция, перед тем как наконец-то сдохнуть, делает последний выдох в виде вызова самой себя, и больше нихуя не делает. Ни сложения, ни умножения — чисто зовёт себя опять. Это как если бы Герасим, вместо того чтобы топиться с Муму, просто крикнул «Мууу!» и пошёл бы спать. Последнее действие, понимаешь?

Вот смотри, пример говнокода, где рекурсия — не хвостовая:

function factorial(n) {
    if (n <= 1) return 1;
    return n * factorial(n - 1); // Умножение после вызова
}

Видишь подвох? После того как factorial(n - 1) отработает, системе ещё нужно вернуться и сделать умножение на n. Значит, каждый вызов надо помнить в стеке, а это — овердохуища памяти, если n большой. Пиздец, а не оптимизация.

А теперь вариант для умных, с хвостовой рекурсией:

function factorial(n, acc = 1) {
    if (n <= 1) return acc;
    return factorial(n - 1, n * acc); // Вызов — последняя операция
}

Вот тут уже красота! После рекурсивного вызова — тишина, блядь. Никаких телодвижений. Теоретически умный движок может выкинуть весь этот цирк со стеками и превратить всё в простой цикл. Чистая магия, ядрёна вошь!

Но вот загвоздка, сука: в ES6 эту оптимизацию вроде как завезли, но доверия к браузерам — ноль ебать. Где-то работает, где-то — хуй с горы. Поэтому если не хочешь подставлять жопу, лучше сразу пиши на циклах. Старо, скучно, зато надёжно, как ёбаный танк.

Короче, хвостовая рекурсия — штука красивая, но в реальной жизни чаще всего — чих-пых тебя в сраку, проще for написать.