clojure - online - ¿Cuál es la diferencia entre las funciones doun dorun doseq y para?
clojure vs scala (2)
¿Cuál es la diferencia entre las funciones doall
, dorun
, doseq
y for
?
Encontré información dispersa en Internet, pero creo que sería mejor centralizar esa información aquí.
Puede ver cómo dorun
y doall
relacionan entre sí mirando el código fuente (simplificado):
(defn dorun [coll]
(when (seq coll) (recur (next coll))))
(defn doall [coll] (dorun coll) coll)
-
dorun
recorre la secuencia, olvidándolo a medida que avanza, y finalmente devuelvenil
. -
doall
devuelve su argumento de secuencia, ahora realizado por eldorun
.
Del mismo modo, podríamos implementar doseq
en términos de dorun
y for
:
(defmacro doseq [seq-exprs & body]
`(dorun (for ~seq-exprs ~@body)))
Por alguna razón, quizás el rendimiento, esto no se hace. La doseq
estándarq está escrita en su totalidad, imitando for
.
dorun
, doall
, y doseq
son para forzar secuencias perezosas, probablemente para obtener efectos secundarios.
-
dorun
: no mantenga ladorun
completa en la memoria mientras fuerza, devuelvenil
-
doall
: mantenga ladoall
completa en la memoria mientras la fuerza (es decir, todo ) y devuelve la secuencia -
doseq
: igual quedorun
, pero te da la oportunidad de hacer algo con cada elemento, ya que es forzado; devuelvenil
for
es diferente en que es una lista de comprensión, y no está relacionada con forzar efectos. doseq
y for
tener la misma sintaxis de enlace, que puede ser una fuente de confusión, pero doseq
siempre devuelve nil
, y for
retorna una doseq
perezosa.