2011-01-18 15 views

Respuesta

141

La diferencia es que for crea una secuencia diferida y la devuelve, mientras que doseq es para la ejecución de efectos secundarios y devuelve nada.

user=> (for [x [1 2 3]] (+ x 5)) 
(6 7 8) 
user=> (doseq [x [1 2 3]] (+ x 5)) 
nil 
user=> (doseq [x [1 2 3]] (println x)) 
1 
2 
3 
nil 

Si desea construir una nueva secuencia basada en otras secuencias, utilícela para. Si desea hacer efectos secundarios (imprimir, escribir en una base de datos, lanzar una ojiva nuclear, etc.) en base a elementos de algunas secuencias, use doseq.

+0

Gran respuesta. ¡Gracias! –

+9

ahora que son muchos los efectos secundarios ... el lanzamiento de una ojiva nuclear :) – Marc

+4

¡Gracias! Tenía mi cabello (desaparecido) con "para" que nunca dispare mis ojivas nucleares sobre mi lista de artículos. "doseq" seguro sí. –

51

Tenga en cuenta también que doseq está ansioso mientras que for es flojo. El ejemplo que faltan en la respuesta de Rayne es

(for [x [1 2 3]] (println x)) 

Al REPL, por regla general, va a hacer lo que quiere, pero eso es básicamente una coincidencia: el REPL obliga a la secuencia perezosa producido por for, haciendo que los printlns sucedan. En un entorno no interactivo, nunca se imprimirá nada. Se puede ver esto en acción mediante la comparación de los resultados de

user> (def lazy (for [x [1 2 3]] (println 'lazy x))) 
#'user/lazy 

user> (def eager (doseq [x [1 2 3]] (println 'eager x))) 
eager 1 
eager 2 
eager 3 
#'user/eager 

Debido a la forma def devuelve la nueva var creado, y no el valor que está ligado a ella, no hay nada para el REPL para imprimir, y lazy se referirá a un lazy-seq no realizado: ninguno de sus elementos ha sido calculado en absoluto. eager se referirá a nil, y se habrá realizado toda su impresión.

+0

¿Cómo maneja la dosisq la evaluación de la secuencia infinitamente floja? ¿mala idea? solo llámalo en secuencias finitas, ya sea ansioso o perezoso? – johnbakers

+0

@johnbakers Bloqueará para siempre hasta que se interrumpa la evaluación. Clojure nunca intenta manejar secuencias infinitas de una manera diferente a las secuencias finitas. –