2015-11-02 73 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。这现在有道理。 –

相关问题