La ricorsione a coda iterativa viene generalmente implementata utilizzando Tail calls. Questa è fondamentalmente una trasformazione di una chiamata ricorsiva in un ciclo semplice.
C# esempio:
uint FactorialAccum(uint n, uint accum) {
if(n < 2) return accum;
return FactorialAccum(n - 1, n * accum);
};
uint Factorial(uint n) {
return FactorialAccum(n, 1);
};
a
uint FactorialAccum(uint n, uint accum) {
start:
if(n < 2) return accum;
accum *= n;
n -= 1;
goto start;
};
uint Factorial(uint n) {
return FactorialAccum(n, 1);
};
o meglio:
uint Factorial(uint n) {
uint accum = 1;
start:
if(n < 2) return accum;
accum *= n;
n -= 1;
goto start;
};
C non # reale ricorsione tail, questo è perché il valore restituito viene modificato la maggior parte dei compilatori non si romperà di questo wn in un ciclo:
int Power(int number, uint power) {
if(power == 0) return 1;
if(power == 1) return number;
return number * Power(number, --power);
}
a
int Power(int number, uint power) {
int result = number;
start:
if(power == 0) return 1;
if(power == 1) return number;
result *= number;
power--;
goto start;
}
La tua prima funzione non è ricorsiva di coda , quindi questo non sarà trasformato in iterazione in Erlang. – Jules
Hai praticamente ragione, ma un buon compilatore dovrebbe essere in grado di vedere la struttura. Modificherò il mio esempio più tardi. – Dykam
+ Si noti che le ultime due azioni prima del salto indietro derivano direttamente dalla chiamata coda. – Dykam