2010-01-13 26 views
8
function move() { 

    pos = pos+1; 

    t = setTimeout(move, 100); 
} 

¿Se puede decir que es recursivo? En caso afirmativo, ¿podría proporcionar alguna referencia?¿Se puede llamar esto recursivo?

+0

No ponga comillas alrededor del nombre de función en setTimeout. Definitivamente no sería recursivo porque nunca se llamaría a la función, solo se hace referencia a ella :-) –

+1

En el mejor de los casos podría llamarse recurrente :) –

Respuesta

13

No, la diferencia entre recursividad (func_a llamadas func_a) o recursión indirecta (func_a llamadas func_b llamadas func_a) es que al usar un temporizador para llamadas repetitivas (desacoplamiento) no crece la pila y se pierde el estado anterior.

+2

Esto es cierto en la repetición de cola en un lenguaje que realiza la optimización de la cola de llamada. En Scheme: '(define (movimiento) (set! Pos (+ pos 1)) (movimiento))' tampoco crecerá la pila, pero ciertamente parece ser recursiva. Como dije en mi respuesta, no hay realmente una línea dura entre algo que es recursivo y algo que no lo es. –

3

No. La función es llamada por una fuente externa (el temporizador), por lo que no es recursiva.

+2

No, * establece * el temporizador. Y luego sale. –

+1

Esto definitivamente no es recursivo. – ChaosPandion

0

No, la función no se llama a sí misma. Sería recursivo si la función se llama dentro del cuerpo del movimiento.

1

Por lo tanto, aquí f1 ("mover") llama a f2 ("setTimeout"), que a su vez llama a f1 nuevamente. Hmm ... esta es una recursión si f2 es una función de devolución de llamada. Pero, si f2 está estableciendo alguna propiedad, como un "tiempo de espera". Esto no es recursividad.

3

Realmente depende de su definición de recursivo, pero yo diría que esto es programar una devolución de llamada que se llama iterativamente, no recursividad.

La recursión consiste en descomponer un problema en problemas más pequeños y similares, hasta llegar a un caso base, y luego posiblemente combinar los resultados de los mismos en una solución. No hay un problema "más pequeño" aquí; solo está programando la misma devolución de llamada para que vuelva a suceder después de un cierto tiempo.

El problema con cualquier tipo de definición dura y rápida es que la recursión se puede implementar en términos de iteración, y viceversa.

Por ejemplo, ¿es esto recursivo?

function state1() { 
    doSomething(); 
    return "state2"; 
} 

function state2() { 
    doSomethingElse(); 
    return "state1"; 
} 

var state = "state1"; 
while (true) { 
    if (state == "state1") { 
     state = state1(); 
    } else { 
     state = state2(); 
    } 
} 

state1 y state1 cada causa la otra para ser llamado; Entonces, en cierto sentido, eso es recursión mutua. Sin embargo, está impulsado por un bucle iterativo, por lo que también podría considerarse iteración.

En un lenguaje que admite la optimización de la cola de llamada, el mismo efecto podría tener las dos funciones recursivamente llamando entre sí (de hecho, incluso en un idioma sin optimización de la cola de llamadas, podría hacerlo, pero lo haría se queda sin espacio de pila muy rápidamente):

function state1() { 
    doSomething(); 
    state2(); 
} 

function state2() { 
    doSomething(); 
    state1(); 
} 

Entonces, la pregunta se convierte en realidad, ¿cómo distinguir si algo es recursivo? ¿El hecho de que una función haga que se la llame nuevamente la vuelve recursiva?

+2

No creo que su ejemplo muestre recursión, parece un simple bucle con llamadas alternas. No hay ningún estado, ya que sería necesario para el cruce de árbol, ya sea que su estado esté en pila o explícitamente manejado. – stacker

+1

En un lenguaje con optimización de cola de llamada (como Scheme), sin embargo, son básicamente equivalentes; el segundo ejemplo tampoco tendría ningún estado en la pila, ya que las llamadas finales le permiten abandonar el marco de pila anterior. Entonces, en un lenguaje con TCO, ¿la solución recursiva de cola repentinamente deja de ser recursiva porque no hace crecer la pila? –

+0

Me hizo aprender sobre la llamada final, en mi opinión, este es un uso innecesario de la recursividad, como el desplazamiento de una lista, si y solo si no tiene necesidad de volver donde estaba antes (esto requeriría el estado). Por cierto, la pregunta está etiquetada como javascript relacionada. – stacker

2

El código en cuestión no es recursividad, ya que el código se llama externamente, no como parte de una ruta de código cíclica a la misma llamada a un método.

Wikipedia tiene una gran página sobre recursividad aquí: Wikipedia: Recursion (computer science)

0

sí lo es .. pero puede ser llamado como la repetición indirecta ..

ejemplo para la repetición directa sería algo como esto:

function factorial (n) 
    { 
     if(n==0) 
    { 
     return(1); 
    } 

    return (n * factorial (n-1)); 
    } 

asimismo otros dijeron .. la función que se hace llamar ..

+0

'setTimeout' no llama' mover'. Simplemente establece 'mover' para ser llamado cuando el tiempo de espera expira y regresa. –

+0

lo que dijo Matthew –

2

yo diría que es un bucle effects Infinidad con un retraso.

Cuando la función retorna, no vuelve a una instancia de llamada anterior de sí misma, por lo tanto, no hay una "pila de llamadas" profunda como suele ser en las recursiones.

+0

¿Qué pasa si la función contiene 'if (pos == 100) dosomething()'? No creo que lo esté pidiendo específicamente para el código dado. –

+0

Lo que veo como una recursión típica es cuando se puede decir "esta tarea se realiza cuando se realizan estas subtareas". Sin embargo, en este caso, el código realiza lo que debería y luego se "llama a sí mismo", pero sin subtarea: este es un ciclo. El código también podría ser 'while (true) {move()} function move() {pos ++}' – naivists

1

técnicamente podría ser ...

function move() { 

    var $this = this; 

    pos = pos+1; 

    t = setTimeout($this, 100); 
} 

pero veo ninguna razón por qué querrías hacer esto. y si realmente quiera conseguir tonto (y bloquear el hilo de su navegador):

function move() { 

    var now = +new Date; 

    pos = pos+1; 

    while((+new Date - now) <= 100){ } 

    move(); 
} 
+0

+1 gracias, acabo de poner el ejemplo limpio en mi publicación, porque no quiero que la gente llame la atención sin relación códigos. – YOU

Cuestiones relacionadas