Reputation: 1820
Why use (reduce + (conj [] (repeat 1 (rand-int 100000))))
instead of simply (list (rand-int 100000))
when they seem to return equivalent results, namely, a list of a single pseudorandomly chosen integer?
The longer version of the random int function is from the book Living Clojure by Carin Meier, in her chapter on core.async, and is to be used to simulate the time servers take to respond.
... we will simulate calling them [two different servers] and having it take a random amount of time. This random amount of time will be a function called
random-add
. It uses arand-int
function that picks a random integer between 0 and 100,000. Then it uses it in a function that will sum up a vector filled with the number 1 of a random length:(defn random-add [] (reduce + (conj [] (repeat 1 (rand-int 100000)))))
[emphasis added]
I'm a beginner, and again really don't see what the advantage is over, for example:
(defn random-add-lite []
(list (rand-int 100000)))
In my repl the results are, as far as I can tell, equivalent. What's the difference and how does it help?
Thanks!
Edit
Here's the entire core.clj
file from the book's core.async
example, so that those interested can see how the rand-int
function is used. I still don't understand, but imagine that as competent a developer as Carin Meier must have had a reason...
(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)))
Upvotes: 2
Views: 469
Reputation: 36708
The key is in this sentence from the book (emphasis mine):
... we will simulate calling them [two different servers] and having it take a random amount of time.
Your suggested function that just does (list (rand-int 100000))
would indeed produce similar results, and would be far more efficient. Your instincts are quite right. But the function in the book is being deliberately inefficient, in order to simulate connecting to a remote server that will take an unknown amount of time to return its result. So in this one case, the inefficient function is better for what the book's author is trying to do. Your function would return in constant, and predictable, time – which would (in this one case) defeat the purpose.
UPDATE: I just checked, and @noisesmith is correct that the arguments to repeat
are swapped. The author is trying to create a list of random length containing only 1s, but she's actually creating a list of length 1 containing a random integer. She should have written (repeat (rand-int 100000) 1)
.
Upvotes: 1