Clojure “tekrar tekrar”, “geleceği” sırayla çalıştırır


12

Bu parçacık

(dorun 
  (map deref 
    (map #(future 
            (println % (Thread/currentThread))) 
         (range 10))))

Farklı iplikleri gösteren 10 karışık çizgi yazdırır:

0 #object[java.lang.Thread 0x5f1b4a83 Thread[clojure-agent-send-off-pool-26,5,main]]                                                                                                                           
2 #object[java.lang.Thread 1 0x79dfba1f #object[Thread[clojure-agent-send-off-pool-28,5,main]java.lang.Thread]                                                                                                 
3 4 #object[java.lang.Thread #object[java.lang.Thread 0x7ef7224f Thread[clojure-agent-send-off-pool-27,5,main]0x5f1b4a83 ]Thread[clojure-agent-send-off-pool-26,5,main]]                                       
5                                                                                                                                                                                                              
67  #object[java.lang.Thread #object[0x79dfba1f java.lang.Thread Thread[clojure-agent-send-off-pool-28,5,main]]0x77526645                                                                                      
 8 #object[java.lang.Thread #object[java.lang.ThreadThread[clojure-agent-send-off-pool-29,5,main] ]9 #object[java.lang.Thread 0xc143aa5 0x7ef7224f                                                             Thread[clojure-agent-send-off-pool-31,5,main]]Thread[clojure-agent-send-off-pool-27,5,main]]                                                                                                                       

0x1ce8675f 0x379ae862 Thread[clojure-agent-send-off-pool-30,5,main]Thread[clojure-agent-send-off-pool-32,5,main]]]

beklediğim gibi, aşağıdaki snippet:

(dorun
  (map deref 
    (map #(future 
            (println % (Thread/currentThread))) 
         (repeatedly 10 #(identity 42)))))

aynı iş parçacığıyla 10 düzgün dizilmiş dizge üretir:

42 #object[java.lang.Thread 0x1e1b7ffb Thread[clojure-agent-send-off-pool-39,5,main]]                                                                                                                              
42 #object[java.lang.Thread 0x1e1b7ffb Thread[clojure-agent-send-off-pool-39,5,main]]                                                                                                                              
42 #object[java.lang.Thread 0x1e1b7ffb Thread[clojure-agent-send-off-pool-39,5,main]]                                                                                                                              
42 #object[java.lang.Thread 0x1e1b7ffb Thread[clojure-agent-send-off-pool-39,5,main]]                                                                                                                              
42 #object[java.lang.Thread 0x1e1b7ffb Thread[clojure-agent-send-off-pool-39,5,main]]                                                                                                                              
42 #object[java.lang.Thread 0x1e1b7ffb Thread[clojure-agent-send-off-pool-39,5,main]]                                                                                                                              
42 #object[java.lang.Thread 0x1e1b7ffb Thread[clojure-agent-send-off-pool-39,5,main]]                                                                                                                              
42 #object[java.lang.Thread 0x1e1b7ffb Thread[clojure-agent-send-off-pool-39,5,main]]                                                                                                                              
42 #object[java.lang.Thread 0x1e1b7ffb Thread[clojure-agent-send-off-pool-39,5,main]]                                                                                                                              
42 #object[java.lang.Thread 0x1e1b7ffb Thread[clojure-agent-send-off-pool-39,5,main]]                          

bu, geleceklerin paralel olarak değil, her biri aynı iş parçacığında çalıştığını açıkça göstermektedir.

Bu repeatedly, sadece diziyi doallilk önce fark etsem bile olur , ancak vektörler, ranges veya diğer diziler paralel yürütme ile sonuçlanır.

Gelecekte neden repeatedlykullanıldığında aynı ileti dizisine gönderiliyor ?

Teşekkürler!

Yanıtlar:


13

Bu çalışıyor:

(dorun (map deref (doall (map #(future (println % (Thread/currentThread))) (repeatedly 10 #(identity 42))))))

Sorun, bir rangeüreten bir yığın halinde ise sekansı repeatedlybir üreten unchunked sekansı. Harita tembeldir, bu yüzden repeatedlybir gelecek yaratıyorsanız, daha sonra onu kaldırırsınız, sonra bir sonraki geleceği yaratır ve sonra kaydı kaldırırsınız. In rangedurumda dizisi tüm gelecekleri oluşturarak ve ardından konum böylece yığın halinde olduğu derefhepsini ing.

Yığınlanmış ve yığınlanmamış dizilerin davranışı arasındaki farkı gözlemlemenin bir başka eğlenceli yolu.

=> (first (map prn (range 10)))
0
1
2
3
4
5
6
7
8
9
nil
=> (first (map prn (repeatedly 10 #(identity 13))))
13
nil

Parçaların boyutu genellikle 32'dir (ancak bence bu hiçbir yerde garanti edilmez), koşarsanız görülebileceği gibi (first (map prn (range 1000))).

Chunking, Clojure'un sizi ilk ısırdığında genellikle öğrendiğiniz gizli özelliklerinden biridir :)


1
çüş! [Komplo Keanu Reaves memehere'yi ekleyin]: Bunun geldiğini görmedim! Harika cevap için teşekkürler!
Rick77

1
Sorun değil! Sadece bu soruyu gördüm çünkü freenode üzerinde #clojure yazdınız.
opqdonut
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.