2015-11-02 74 views
2

爲什麼使用(reduce + (conj [] (repeat 1 (rand-int 100000))))而不是簡單的(list (rand-int 100000))當他們似乎返回相同的結果,即一個單一的僞隨機選擇的整數列表?在Clojure中,爲什麼rand-int的使用如此複雜?

隨機int函數的較長版本來自Carin Meier在她的core.async一章中的Living Clojure,它將用於模擬服務器響應的時間。

...我們將模擬調用它們[兩臺不同的服務器]並讓它花費隨機數量的時間。這個隨機數量的時間將被稱爲random-add。它使用一個rand-int函數來選擇0到100,000之間的隨機整數。 然後,它使用它在將總結填充有隨機長度的數目1的矢量的函數:

我是初學者

(defn random-add [] 
    (reduce + (conj [] (repeat 1 (rand-int 100000))))) 

[加上強調]並再次實在看不出優點是什麼了,例如:

(defn random-add-lite [] 
    (list (rand-int 100000))) 

在我REPL結果是,據我所知道的,相同的。有什麼區別,它有什麼幫助?

謝謝!

編輯

下面是書中的core.async例如整個core.clj文件,讓那些有興趣的可以看到rand-int功能的使用方式。我還是不明白,但試想,作爲主管開發的卡琳·邁爾必須有一個理由...

(ns async-tea-party.core 
(:gen-class) 
(:require [clojure.core.async :as async])) 

(def google-tea-service-chan (async/chan 10)) 
(def yahoo-tea-service-chan (async/chan 10)) 
(def result-chan (async/chan 10)) 

(defn random-add [] 
    (reduce + (conj [] (repeat 1 (rand-int 100000))))) 

(defn request-google-tea-service [] 
    (async/go 
    (random-add) 
    (async/>! google-tea-service-chan 
       "tea complimemts of google"))) 

(defn request-yahoo-tea-service [] 
    (async/go 
    (random-add) 
    (async/>! yahoo-tea-service-chan 
       "tea complimemts of yahoo"))) 

(defn request-tea [] 
    (request-google-tea-service) 
    (request-yahoo-tea-service) 
    (async/go (let [[v] (async/alts! 
         [google-tea-service-chan 
         yahoo-tea-service-chan])] 
       (async/>! result-chan v)))) 

(defn -main [& args] 
    ;; TODO - it seems wasteful to only request one cup 
    ;; of tea - so do at least 1000 
    (println "Requesting tea") 
    (request-tea) 
    (println (async/<!! result-chan))) 
+1

我想知道重複的參數是否在這裏交換?因爲如果交換了arg命令,粗體註釋會更有意義(調用reduce的奇怪步驟也是如此)。 – noisesmith

+1

是的,我剛剛檢查過,重複的參數被交換。它們應該是'(repeat(rand-int 100000)1)',這將創建一個隨機長度的列表。相反,作者錯誤地創建了一個包含一個隨機整數的長度爲1的列表,這不是她的意圖。有關更多詳情,請參閱下面的答案。 – rmunn

回答

1

的關鍵是從書(重點煤礦)的這句話:

...我們將模擬美其名曰[兩個不同的服務器]和有它需要的時間隨機量。

您的建議功能(list (rand-int 100000))確實會產生類似的結果,而且效率會更高。你的直覺是對的。但是,本書中的功能是故意效率低下,爲了模擬連接到遠程服務器,將需要一段未知的時間來返回其結果。所以在這個一個的情況下,效率低下的功能對本書作者試圖做的事情會更好。你的函數會以不變的和可預測的時間返回 - 這將會(在這種情況下)擊敗目的。

UPDATE:我剛剛檢查過,並且@noisesmith正確,表示repeat的參數已被交換。作者試圖創建一個只包含1的隨機長度列表,但她實際上創建了一個包含隨機整數的長度爲1的列表。她應該寫下(repeat (rand-int 100000) 1)

+0

神祕解決,感謝你和noisesmith。這現在有道理。 –

相關問題