Funkcję opartą na pętli typu (kod pseudo-java z rozpakowywaniem krotek):
Typ1 funkcja(TypP1 p1, TypP2 p2, ...., TypPN pN) {
TypL1 l1 = w1;
TypL2 l2 = w2;
...
TypLN lN = wN;
while (warunek) {
(l1, l2, ..., lN) = funkcja1(p1, p2, ..., pN, l1, l2, ..., lN);
}
return funkcja2(p1, p2, ..., pN, l1, l2, ..., lN);
}
Możesz trywialnie zamienić na rekurencję w taki sposób:
Typ1 funkcjaWstępna(TypP1 p1, TypP2 p2, ..., TypPN pN) {
TypL1 l1 = w1;
TypL2 l2 = w2;
...
TypLN lN = wN;
return funkcjaRekursywna(p1, p2, ..., pN, l1, l2, ..., lN);
}
Typ1 funkcjaRekursywna(TypP1 p1, TypP2 p2, ..., TypPN pN, TypL1 l1, TypL2, ..., TypLN lN) {
if (warunek) {
return funkcjaRekursywna(p1, p2, ..., pN, rozpakujKrotkę(funkcja1(p1, p2, ..., pN, l1, l2, ..., lN));
} else {
return funkcja2(p1, p2, ..., pN, l1, l2, ..., lN);
}
}
p1, p2, etc to parametry (tutaj stałe, bo nie lubię podmieniać parametrów w środku funkcji)
l1, l2 etc to zmienne (w wersji pierwszej)/ stałe (w wersji drugiej) lokalne (po konwersji stają się parametrami)
Powstała rekurencja to rekurencja ogonowa, więc kompilator z TCO (tail call optimization) jest w stanie zamienić drugą postać z powrotem na pętlę.
pozdro :]