Вы можете использовать тот же аргумент для любого преобразования, которое выполняет компилятор.Например, когда вы используете C #, вы когда-нибудь использовали лямбда-выражения или анонимные делегаты?Если компилятор просто собирается превратить их в классы и (неанонимные) делегаты, то почему бы просто не использовать эти конструкции самостоятельно?Точно так же вы когда-нибудь использовали блоки итераторов?Если компилятор просто собирается превратить их в конечные автоматы, которые явно реализуют IEnumerable<T>
, то почему бы просто не написать этот код самостоятельно?Или, если компилятор C # просто собирается испускать IL, зачем вообще писать C # вместо IL?И так далее.
Один очевидный ответ на все эти вопросы заключается в том, что мы хотим написать код, который позволяет нам четко выражать свои мысли.Аналогично, существует множество алгоритмов, которые являются естественно рекурсивными, и поэтому написание рекурсивных функций часто приводит к четкому выражению этих алгоритмов.В частности, возможно, легче рассуждать о завершении рекурсивного алгоритма, чем цикла while во многих случаях (например, существует ли четкий базовый случай, и делает ли каждый рекурсивный вызов проблему "меньшей"?).
Однако, поскольку мы пишем код, а не математические статьи, также неплохо иметь программное обеспечение, которое соответствует определенным реальным критериям производительности (например, возможность обрабатывать большие входные данные без переполнения стека).Поэтому тот факт, что хвостовая рекурсия преобразуется в эквивалент циклов while, имеет решающее значение для возможности использования рекурсивных формулировок алгоритмов.