Yanıtlar:
Aradaki fark, for
tembel bir dizi oluşturması ve bunu doseq
yan etkileri yürütmek için döndürmesi ve sıfır döndürmesidir.
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
Diğer dizilere göre yeni bir dizi oluşturmak istiyorsanız, için kullanın. Bazı sekanslardan gelen öğelere dayalı yan etkiler (yazdırma, veritabanına yazma, nükleer savaş başlığı başlatma vb.) Yapmak istiyorsanız, dozq kullanın.
Ayrıca doseq
tembelken hevesli olduğunu da unutmayın for
. Rayne'in cevabında eksik olan örnek şudur:
(for [x [1 2 3]] (println x))
REPL'de, bu genellikle istediğinizi yapar, ancak bu temelde bir tesadüf: REPL, tarafından üretilen tembel diziyi for
zorlayarak baskıların gerçekleşmesine neden olur. Etkileşimli olmayan bir ortamda hiçbir şey basılmayacaktır. Bunu sonuçlarını karşılaştırarak görebilirsiniz.
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
Çünkü def
formu yeni oluşturulan /var,...vb değil kendisine bağlı olduğu değer döndürür, orada yazdırmak için repl için yok ve bekleyen lazy
gerçekleşmemiş bir tembel-seq sevk edecektir: kendi elemanlarının hiçbiri hiç bilgisayarlı edilmiştir. eager
başvuracak nil
ve tüm baskısı yapılmış olacaktır.