2012-07-08 9 views
5

La función Clojure¿Por qué una función Clojure que consiste únicamente en llamadas a funciones diferidas no es tan vaga?

(reductions + 0 (cycle [1 1 -1])) 

produce una secuencia [0 1 2 1 2 3 2 3 4 3 4 5 ...]. Desafortunadamente, esta secuencia no es floja.

Como cycle y reductions están documentados como secuencias de retorno de espera, esperaba que esta combinación de esas funciones también devolviera una secuencia perezosa. ¿Por qué no y cómo puedo solucionarlo para devolver la secuencia perezosamente?

Un ejemplo más complejo que presenta el mismo problema:

(reductions (fn [x f] (f x)) 0 (cycle [inc inc dec])) 

(muestro esto, porque este es el tipo de versión me gustaría tener trabajo, al final, en caso de que haga alguna diferencia)

Respuesta

9

Desafortunadamente, esta secuencia no es floja.

Oh, sí, lo es. Podemos comprobar rápidamente que es perezoso tomando sus primeros 10 elementos:

(take 10 (reductions + 0 (cycle [1 1 -1]))) 

Esto devuelve muy rápidamente una respuesta, lo que demuestra la secuencia es perezoso. Si la función no fuera floja, trataría de realizar todos los elementos en la secuencia infinita, y volaría la memoria, o colgaría en un ciclo infinito.

Lo que sucede es que está escribiendo esta función en REPL, que intenta realizar la secuencia antes de mostrársela.

Editar: Utilice este consejo para stop infinite loops si alguna vez descubrió que ha activado uno o ha intentado accidentalmente realizar una secuencia infinita.

+0

Gracias :). Traté de aliasing la secuencia por una declaración (def ...) para evitar eso, pero por supuesto (ahora me doy cuenta) que no funciona. Nombrarlo con un (defn ...) funciona bien. – Confusion

+1

¿Una forma más precisa de comprobar si una función es floja es envolviéndola en realización? . Si eso devuelve falso, la función es floja. => (¿Realizado? (reducciones +0 (ciclo [1 1 -1]))) falso – NielsK

+1

'realizó?' funciona muy mal para este propósito (de hecho, para la mayoría de los propósitos, con suerte se mejora pronto). Intenta 'realízalo 'en todos estos valores:' [] ',' nil', '' (a b c)', '(iterate inc 0)', y verás a qué me refiero. – amalloy

Cuestiones relacionadas