online - Diferencia entre doseq y para en Clojure
clojure vs scala (2)
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.
¿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.