Qual é a diferença entre doseq e for em Clojure? Quais são alguns exemplos de quando você escolheria usar um em vez do outro?
105
A diferença é que for
cria uma sequência preguiçosa e a retorna enquanto doseq
é para a execução de efeitos colaterais e retorna nulo.
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
Se você deseja construir uma nova sequência baseada em outras sequências, use para. Se você quiser fazer efeitos colaterais (imprimir, gravar em um banco de dados, lançar uma ogiva nuclear, etc.) com base em elementos de algumas sequências, use o doseq.
Observe também que
doseq
é ansioso enquantofor
é preguiçoso. O exemplo que falta na resposta de Rayne éNo REPL, isso geralmente fará o que você quiser, mas isso é basicamente uma coincidência: o REPL força a sequência preguiçosa produzida por
for
, fazendo com que as impressões aconteçam. Em um ambiente não interativo, nada será impresso. Você pode ver isso em ação comparando os resultados deComo o
def
formulário retorna a nova var criada, e não o valor que está vinculado a ela, não há nada para o REPL imprimir elazy
se referirá a um lazy-seq não realizado: nenhum de seus elementos foi calculado.eager
irá se referir anil
, e todas as suas impressões terão sido feitas.fonte