【问题标题】:In Clojure, why is this use of rand-int so complex?在 Clojure 中,为什么 rand-int 的使用如此复杂?
【发布时间】:2015-11-02 11:50:14
【问题描述】:

为什么要使用(reduce + (conj [] (repeat 1 (rand-int 100000)))) 而不是简单的(list (rand-int 100000)),因为它们似乎返回等效结果,即单个伪随机选择整数的列表?

随机 int 函数的较长版本来自 Carin Meier 的书 Living Clojure,在她关于 core.async 的章节中,用于模拟服务器响应所需的时间。

...我们将模拟调用它们 [两个不同的服务器] 并让它花费随机的时间。这个随机时间量将是一个名为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 函数是如何使用的。我还是不明白,但想象一下,像 Carin Meier 这样有能力的开发人员一定是有原因的……

  (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)))

【问题讨论】:

  • 我想知道重复的参数是否在这里交换?因为如果您交换 arg 顺序,粗体注释会更有意义(调用 reduce 的奇怪步骤也是如此)。
  • 是的,我刚刚检查并交换了 repeat 的参数。它们应该是(repeat (rand-int 100000) 1),这将创建一个随机长度的列表。相反,作者错误地创建了一个包含单个随机整数的长度为 1 的列表,这不是她想要的。有关详细信息,请参阅下面的答案。

标签: random clojure


【解决方案1】:

关键在于书中的这句话(重点是我的):

...我们将模拟调用它们 [两个不同的服务器] 并让它花费随机的时间。

您建议的仅执行(list (rand-int 100000)) 的函数确实会产生类似的结果,并且效率更高。你的直觉是完全正确的。但是书中的函数故意效率低下,以便模拟连接到需要未知时间才能返回结果的远程服务器。所以在这个 one 的例子中,低效的函数更适合本书作者试图做的事情。您的函数将以恒定且可预测的时间返回——这(在这种情况下)会破坏目的。

更新:我刚刚检查过,@noisesmith 是正确的,repeat 的参数被交换了。作者试图创建一个仅包含 1 的随机长度列表,但她实际上是在创建一个包含随机整数的长度为 1 的列表。她应该写(repeat (rand-int 100000) 1)。

【讨论】:

  • 谜团解开了,感谢您和noisesmith。现在这是有道理的。
猜你喜欢
  • 1970-01-01
  • 2019-10-01
  • 2017-10-27
  • 2012-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-24
相关资源
最近更新 更多