recursividad en clojure

Estoy tratando de hacer que este programa de muestra funcione

(defn foo
  ([x] (foo x []))
  ([x current]
     (when (> x 0)
       (recur (dec x) (conj current x)))))

Cuando llamo a esta función (foo 5), debería obtener [1 2 3 4 5], sin embargo, solo devuelve cero. ¿Qué estoy haciendo mal?

Gracias, Murtaza

preguntado el 12 de junio de 12 a las 12:06

3 Respuestas

Su recursividad no tiene una expresión de retorno, es decir, cuando entonces when es falso, la recursión termina y devuelve nil. Puedes arreglar esto usando if como:

(defn foo
  ([x] (foo x []))
  ([x current]
     (if (> x 0)
       (recur (dec x) (conj current x))
       current)))

Esto volverá [5 4 3 2 1] para (foo 5) ya que está utilizando el vector como valor de retorno y conj on vector añade el elemento al final del vector. Puede invertir el vector o usar la lista, es decir, en lugar de (foo x []) utilizado (foo x '())

Respondido el 12 de junio de 12 a las 12:06

Por lo general, prefiero la condición de salida primero, ya que me resulta más fácil de leer. - Dan Lebrero

Otro punto de vista podría ser tener el caso de retorno/salida al final, ya que la mayoría de las personas también están acostumbradas cuando miran algún código de función en otros idiomas :) - Ankur

El siguiente código funciona. No estaba devolviendo el valor final.

(defn foo
  ([x] (foo x []))
  ([x current]
     (if (> x 0)
       (recur (dec x) (conj current x))
       current)))

Respondido el 12 de junio de 12 a las 12:06

He corregido su programa original para usar (if (= x 0) en lugar de (when (> x 0), y esto vuelve [1 2 3 4 5].

(defn foo
  ([x] (foo x []))
  ([x current]
     (if (= x 0)
       (apply vector (sort < current))
       (recur (dec x) (conj current x)))))

Respondido el 12 de junio de 12 a las 14:06

La respuesta de Ankur es mejor ya que (foo -1) devuelve []. Su versión causará un OOM en este caso. - Dan Lebrero

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.