Sí, algunos lenguajes y compiladores convertirán la lógica recursiva en lógica no recursiva. Esto se conoce como optimización de llamadas de cola : tenga en cuenta que no todas las llamadas recursivas son optimizables. En esta situación, el compilador reconoce una función de la forma:
int foo(n) {
...
return bar(n);
}
Aquí, el lenguaje puede reconocer que el resultado que se devuelve es el resultado de otra función y cambiar una llamada de función con un nuevo marco de pila en un salto.
Darse cuenta de que el método factorial clásico:
int factorial(n) {
if(n == 0) return 1;
if(n == 1) return 1;
return n * factorial(n - 1);
}
no se puede optimizar la llamada de cola debido a la inspección necesaria en la devolución.
Para hacer esta llamada de cola optimizable,
int _fact(int n, int acc) {
if(n == 1) return acc;
return _fact(n - 1, acc * n);
}
int factorial(int n) {
if(n == 0) return 1;
return _fact(n, 1);
}
Compilar este código con gcc -O2 -S fact.c
(el -O2 es necesario para habilitar la optimización en el compilador, pero con más optimizaciones de -O3 se hace difícil para un humano leer ...)
_fact:
.LFB0:
.cfi_startproc
cmpl $1, %edi
movl %esi, %eax
je .L2
.p2align 4,,10
.p2align 3
.L4:
imull %edi, %eax
subl $1, %edi
cmpl $1, %edi
jne .L4
.L2:
rep
ret
.cfi_endproc
Uno puede ver en el segmento .L4
, en jne
lugar de un call
(que hace una llamada de subrutina con un nuevo marco de pila).
Tenga en cuenta que esto se hizo con C. La optimización de llamadas de cola en java es difícil y depende de la implementación de JVM: tail-recursion + java y tail-recursion + optimization son buenos conjuntos de etiquetas para navegar. Puede encontrar que otros lenguajes JVM pueden optimizar mejor la recursividad de cola (intente clojure (que requiere la recurrencia para optimizar la llamada de cola) o scala).
return recursecall(args);
la recursividad, la materia más compleja es posible mediante la creación de una pila explícita y sinuoso hacia abajo, pero dudo que lo harán