Вы всегда можете превратить рекурсивную функцию в итеративную? Да, абсолютно, и тезис Церкви-Тьюринга доказывает это, если память служит. В простых терминах он утверждает, что вычислимое рекурсивными функциями вычислимо с помощью итеративной модели (такой как машина Тьюринга) и наоборот. Тезис не говорит вам точно, как сделать преобразование, но он говорит, что это определенно возможно.
Во многих случаях преобразование рекурсивной функции легко. Кнут предлагает несколько методов в «Искусстве компьютерного программирования». И часто, вычисленная рекурсивно вещь может быть вычислена с помощью совершенно другого подхода за меньшее время и пространство. Классическим примером этого являются числа Фибоначчи или их последовательности. Вы наверняка встретили эту проблему в своем плане степени.
На оборотной стороне этой монеты мы, конечно же, можем представить, что система программирования настолько усовершенствована, чтобы рассматривать рекурсивное определение формулы в качестве приглашения запоминать предыдущие результаты, тем самым предлагая преимущество в скорости без хлопот о том, чтобы сообщить компьютеру точно какие шаги следует при вычислении формулы с рекурсивным определением. Дейкстра почти наверняка представила такую систему. Он долго пытался отделить реализацию от семантики языка программирования. С другой стороны, его языки без детерминированного и многопроцессорного программирования находятся в лиге выше практического профессионального программиста.
В конечном счете, многие функции проще понять, прочитать и записать в рекурсивной форме. Если нет веской причины, вы, вероятно, не должны (вручную) преобразовывать эти функции в явно итеративный алгоритм. Ваш компьютер будет правильно обрабатывать эту работу.
Я вижу одну вескую причину. Предположим, что у вас прототипная система на языке супервысокого уровня, например [белье для белья асбеста] Схема, Lisp, Haskell, OCaml, Perl или Pascal. Предположим, что условия таковы, что вам нужна реализация на C или Java. (Возможно, это политика.) Тогда вы, безусловно, могли бы записать некоторые функции, написанные рекурсивно, но которые, в буквальном переводе, взорвут вашу систему времени исполнения. Например, бесконечная рекурсия хвоста возможна в Схеме, но одна и та же идиома вызывает проблему для существующих сред C. Другим примером является использование лексически вложенных функций и статической области, которую поддерживает Pascal, но C не делает этого.
В этих условиях вы можете попытаться преодолеть политическое сопротивление исходному языку. Возможно, вы ошибаетесь, переоценивая Лиспа, как в десятом законе Гринспуна. Или вы можете просто найти совершенно другой подход к решению. Но в любом случае, безусловно, есть способ.
Я не вижу, как это контрпример. Техника стека будет работать. Это будет некрасиво, и я не собираюсь писать это, но это выполнимо. Похоже, akdas признает, что в вашей ссылке. –
Ваш (num-way x y) является просто (x + y) 'select' x = (x + y)!/(X! Y!), Который не нуждается в рекурсии. – ShreevatsaR
Дубликат: http://stackoverflow.com/questions/531668/ –