Diferencia entre doseq y para en Clojure

¿Cuál es la diferencia entre doseq y para en Clojure? ¿Cuáles son algunos ejemplos de cuándo elegirías usar uno sobre el otro?

La diferencia es que construye una secuencia diferida y la devuelve mientras doseq es para ejecutar 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, use 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.

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

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

En el REPL, generalmente hará lo que quiera, pero eso es básicamente una coincidencia: el REPL fuerza la secuencia floja producida por for , causando que las impresiones ocurran. En un entorno no interactivo, nunca se imprimirá nada. Puedes ver esto en acción al comparar 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 

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