Czy zawsze możesz zamienić funkcję rekurencyjną na iteracyjną? Tak, absolutnie, a teza Kościoła Turinga dowodzi, że pamięć służy. Mówiąc ogólnie, stwierdza, że to, co można obliczać za pomocą funkcji rekurencyjnych, można obliczać za pomocą modelu iteracyjnego (takiego jak maszyna Turinga) i odwrotnie. Teza nie mówi ci dokładnie, jak wykonać konwersję, ale mówi, że jest to zdecydowanie możliwe.
W wielu przypadkach konwersja funkcji rekurencyjnej jest łatwa. Knuth oferuje kilka technik w „Sztuce programowania komputerowego”. Często rzecz obliczana rekurencyjnie może być obliczana przy użyciu zupełnie innego podejścia w krótszym czasie i przestrzeni. Klasycznym tego przykładem są liczby Fibonacciego lub ich sekwencje. Z pewnością spotkałeś ten problem w swoim planie studiów.
Z drugiej strony tej monety możemy z pewnością wyobrazić sobie system programowania tak zaawansowany, aby traktować rekurencyjną definicję formuły jako zaproszenie do zapamiętania wcześniejszych wyników, oferując w ten sposób korzyści prędkości bez kłopotu z informowaniem komputera, które kroki należy wykonać wykonaj obliczenia formuły z definicją rekurencyjną. Dijkstra prawie na pewno wymyślił taki system. Spędził dużo czasu próbując oddzielić implementację od semantyki języka programowania. Z drugiej strony, jego niedeterministyczne i wieloprocesowe języki programowania znajdują się w lidze ponad ćwiczącym profesjonalnym programistą.
W końcowej analizie wiele funkcji jest po prostu łatwiejszych do zrozumienia, czytania i pisania w formie rekurencyjnej. O ile nie ma ważnego powodu, prawdopodobnie nie powinieneś (ręcznie) konwertować tych funkcji do jawnie iteracyjnego algorytmu. Twój komputer poprawnie obsłuży to zadanie.
Widzę jeden ważny powód. Załóżmy, że masz prototypowy system w języku wysokiego poziomu, takim jak [ zakładanie bielizny z azbestu ] Scheme, Lisp, Haskell, OCaml, Perl lub Pascal. Załóżmy, że warunki są takie, że potrzebujesz implementacji w C lub Javie. (Być może jest to polityka.) Wtedy z pewnością można by napisać rekursywnie niektóre funkcje, które, dosłownie przetłumaczone, mogłyby zniszczyć twój system wykonawczy. Na przykład, nieskończona rekurencja ogona jest możliwa na Schemacie, ale ten sam idiom powoduje problem w istniejących środowiskach C. Innym przykładem jest użycie funkcji zagnieżdżonych leksykalnie i zakresu statycznego, które Pascal obsługuje, ale C nie.
W tych okolicznościach możesz spróbować przezwyciężyć polityczny opór wobec oryginalnego języka. Może się zdarzyć, że źle wdrażasz Lisp, tak jak w dziesiątym prawie Greenspuna (z przymrużeniem oka). Lub możesz po prostu znaleźć zupełnie inne podejście do rozwiązania. Ale w każdym razie jest na pewno sposób.