I came across an example on futures in Clojure by example
(let [sleep-and-wait
(map (fn [time]
(future
(Thread/sleep time)
(println (str "slept " time " sec" ))))
[4000 5000])]
(doall (map deref sleep-and-wait))
(println "done"))
Since map produces a lazy sequence I expect that future is not started, until we call deref on it. deref is expected to block until future returns a result. We map elements sequentially, so I expected this code to run 9 sec, but it runs in 5.
Could someone explain why?
Clojure lazy-seqs make no promise to be maximally lazy.
+user=> (take 1 (for [i (range 1000)] (doto i (println " - printed"))))
(0 - printed
1 - printed
2 - printed
3 - printed
4 - printed
5 - printed
6 - printed
7 - printed
8 - printed
9 - printed
10 - printed
11 - printed
12 - printed
13 - printed
14 - printed
15 - printed
16 - printed
17 - printed
18 - printed
19 - printed
20 - printed
21 - printed
22 - printed
23 - printed
24 - printed
25 - printed
26 - printed
27 - printed
28 - printed
29 - printed
30 - printed
31 - printed
0)
when seq is called on a vector (most lazy operations implicitly call seq on their collection argument), it produces a chunked data type, which realizes batches of results at a time, instead of one by one. If you need to control the consumption of your data, you can do something that forces unchunking.
+user=>
(defn unchunk [s]
(when (seq s)
(lazy-seq
(cons (first s)
(unchunk (rest s))))))
#'user/unchunk
+user=> (take 1 (for [i (unchunk (range 1000))] (doto i (println " - printed"))))
(0 - printed
0)
of course, the simpler option in this case is to use a type that isn't chunked
+user=> (take 1 (for [i (take 1000 (iterate inc 0))] (doto i (println " - printed"))))
(0 - printed
0)
This could be connected with the nature of the map function: it doesn't take the elements of mapped collection one by one, rather it does it by chunks for optimization. Here is a small example:
user> (defn trace [x]
(println :realizing x)
x)
#'user/trace
user> (def m (map trace (range 1000)))
#'user/m
user> (first m)
:realizing 0
:realizing 1
:realizing 2
...
:realizing 30
:realizing 31
0
so in your case when you call map, it doesn't start one future in a separate thread, rather it starts both of them, and as a result you just block until the longest-running thread finishes (and it lasts for 5 s)
Related
We've been given a task to print the first ten multiples of any number for which we have written the below code. It is throwing an error. In simple words, if n is 2 then we need to create a table of 2's till 10.
(defn multiples [n]
(while ( n < 11)
(println( n * n))
(swap! n inc)))
(def n (Integer/parseInt (clojure.string/trim (read-line))))
(multiples n)
With this, we're getting the error:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.
(defn multiples [n]
(map #(* n %) (range 1 (+ 10 1))))
user=> (multiples 1)
;; => (1 2 3 4 5 6 7 8 9 10)
user=> (multiples 2)
;; => (2 4 6 8 10 12 14 16 18 20)
The resulting list you can loop over and println each of the elements.
(for [i (multiples 2)]
(println i))
;; or:
(map println (multiples 2)) ;; though one usually doesn't apply
;; `map` on side effect functions ...
To improve your own construct:
You, coming from an imperative language, try to work with mutations.
That is very un-idiomatic clojure.
However, by declaring a value atom, you can access using the # operator to its place. And mutate the variable's value.
(defn multiples [n]
(let [i (atom 1)] ;; i is an atom
(while (< #i 11) ;; #i is the value saved into i
(println (* #i n))
(swap! i inc)))) ;; and correctly you can increase the value
With this multiples, you can also print the values.
You can't apply swap! to normal variables, only to atoms.
while loops one should apply only if number of elements not known.
In this case, one knows very well, when to stop. So use rather
a for loop.
(defn multiples [n]
(for [i (range 1 11)]
(println (* i n))))
Look at what iterate function does here
(defn multiples-of [n]
(iterate (partial * n) n))
(def ten-multiples-of-ten
(take 10 (multiples-of 10)))
EDIT: I misread the author of the question, I believe he wants to just generate a sequence of squares. Here is one way using transducers, cause why not ;)
(def xf
(comp
(map inc)
(map #(* % %))))
(defn first-n-squares [n]
(into [] xf (take n (range))))
You can use recur in a loop:
(defn multiples [n]
(if (< n 11)
(do ; then
(println (* n n))
(recur (inc n)))
nil)) ; else return nil
Running this by invoking
(multiples 1)
in a REPL will produce
1
4
9
16
25
36
49
64
81
100
nil
I'd like to be able to wait on a group of functions. I want them to execute in parallel, but block until the last future is done. (I don't want them to execute sequentially, like with (do #(future-1) #(future-2)))
Something like
(declare long-running-fn-1)
(declare long-running-fn-2)
(let [results (wait-for-all
(long-running-fn-1 ...)
(long-running-fn-2 ...)]
(println "result 1" (first results)
(println "result 2" (second results))
Futures are added to the same thread pool used for send the moment they're defined. As long as there are enough free threads in that pool (size of which will be slightly larger than your available number of CPU cores), calculation starts immediately.
The problem with (doall #(future ...) #(future ...)) is that the second future isn't created until after the first one is deref'd.
Here's a slightly modified version of your code that defines both futures (starting their calculation) before deref'ing either of them; you'll see it takes only 5 seconds rather than 10:
(time
(let [future-1 (future (Thread/sleep 5000))
future-2 (future (Thread/sleep 5000))]
[#future-1 #future-2]))
here is one more example, illustrating the parallel execution + sync dereferencing:
(letfn [(mk-fut [sleep-ms res]
(future
(Thread/sleep sleep-ms)
(println "return" res "after" sleep-ms "ms")
res))]
(let [futures (mapv mk-fut
(repeatedly #(rand-int 2000))
(range 10))]
(mapv deref futures)))
;; return 3 after 104 ms
;; return 8 after 278 ms
;; return 0 after 675 ms
;; return 6 after 899 ms
;; return 1 after 928 ms
;; return 2 after 1329 ms
;; return 9 after 1383 ms
;; return 4 after 1633 ms
;; return 5 after 1931 ms
;; return 7 after 1972 ms
;;=> [0 1 2 3 4 5 6 7 8 9]
(the order of the output prints would differ between calls, while the resulting vector would be the same) You can see that all of the futures run in parallel, while generated and dereferenced in particular order.
Use pcalls or pvalues:
test1.core=> (pcalls #(inc 1) #(dec 5))
(2 4)
test1.core=> (pvalues (inc 1) (dec 5))
(2 4)
Internally they use pmap which executes functions in parallel and return lazy sequence of results when all functions are processed.
I´m new to clojure and am trying to break through some of the walls I keep running into. The code in question is the function v3 which should accept 4 arguments:
a min and a max integer, mi and ma, to use with the
random-numbers function to find numbers within a certain range,
another integer,cnt, to signify how many numbers I want in my
final list, and
tones, which is a list of integers that the randomized numbers have
to match once I've calculated modulo 12 of said numbers.
The function should run until o is a list of length cnt containing random numbers that are also in the tones list.
My document compiles just fine but when I want to run the function itself in a repl, for example using something like (v3 58 52 15 '(0 2 4 5 7 9)) I get the following error:
ClassCastException clojure.langLazySeq cannot be cast to java.lang.Number clojure.langNumbers.reminder (Numbers.java:173)
Here's my code
(defn random-numbers [start end n]
(repeatedly n #(+ (rand-int (- end start)) start)))
(defn m12 [input]
(mod input 12))
(defn in? [coll elm]
(some #(= elm %) coll))
(defn v3 [ma mi cnt tones]
(let [o '()]
(loop []
(when(< (count o) cnt)
(let [a (m12 (random-numbers mi ma 1))]
(if (in? tones a)
(conj o a)))))
(println o)))
First of all, it is more idiomatic Clojure to type the parentheses on the same line, and not in the "Java"-way.
When I debug your code I see it fails at the call to m12: random-numbers returns a sequence and the call to mod in m12 expects a number.
You can fix this issue by for example taking the first element from the sequence returned by random-numbers:
(defn v3
[ma mi cnt tones]
(let [o '()]
(loop []
(when (< (count o) cnt)
(let [a (m12 (first (random-numbers mi ma 1)))]
(if (in? tones a)
(conj o a)))))
(println o)))
/edit
I am not sure what your code is supposed to be doing, but this did not stop me to make some more changes. If you use a loop, you usually also see a recur to "recur" back to the loop target. Otherwise it does not do much. I added the following things:
a recur to the loop.
The let statement added to the loop vector (starting value).
println statements in the false clause of the if-statement.
Removed the first if-statement that checked the count
Changed list to vector. You would use a list over a vector when you create code structures structure (for example while writing macros).
See:
(defn v3
[ma mi cnt tones]
(loop [o []]
(if (< (count o) cnt)
(let [a (m12 (first (random-numbers mi ma 1)))]
(if (in? tones a)
(recur (conj o a))
(println "a not in tones, o:" o)))
(println "already " cnt "tones generated"))))
If you run (v3 58 52 4 [0 2 4 5 7 9]) (note I changed your 15 for cnt to 4 and changed the list to a vector) a few times you get for example the following output:
a not in tones, o: [4 4]
a not in tones, o: [9 5 5]
a not in tones, o: []
already 4 tones generated
a not in tones, o: [7]
Hope this helps.
I think I see what you are trying to do.
This is an exercise in automatic composition. Your v3 function is intended to generate a sequence of tones
in a range given by min and max.
with tone class drawn from a given set of tone classes (tones)
The m12 function returns the tone class of a tone, so let's call it that:
(defn tone-class [tone]
(mod tone 12))
While we're about it, I think your random-number function is easier to read if we add the numbers the other way round:
(defn random-number [start end]
(+ start (rand-int (- end start))))
Notice that the possible values include start but not end, just as the standard range does.
Apart from your various offences against clojure semantics, as described by #Erwin, there is a problem with the algorithm underlying v3. Were we to repair it (we will), it would generate a sequence of tone classes, not tones. Interpreted as tones, these do not move beyond the base octave, however wide the specified tone range.
A repaired v3
(defn v3 [mi ma cnt tones]
(let [tone-set (set tones)]
(loop [o '()]
(if (< (count o) cnt)
(let [a (tone-class (random-number mi ma))]
(recur (if (tone-set a) (conj o a) o)))
o))))
For a start, I've switched the order of mi and ma to conform with
range and the like.
We turn tones into a set, which therefore works as a
membership function.
Then we loop until the resulting sequence, o, is big enough.
We return the result rather than print it.
Within the loop, we recur on the same o if the candidate a doesn't fit, but on (conj o a) if it does. Let's try it!
(v3 52 58 15 '(0 2 4 5 7 9))
;(4 5 9 7 7 5 7 7 9 7 5 7 4 9 7)
Notice that neither 0 nor 2 appears, though they are in tones. That's because the tone range 52 to 58 maps into tone class range 4 to 10.
Now let's accumulate tones instead of tone classes. We need to move conversion inside the test, replacing ...
(let [a (tone-class (random-number mi ma))]
(recur (if (tone-set a) (conj o a) o)))
... with ...
(let [a (random-number mi ma)]
(recur (if (tone-set (tone-class a)) (conj o a) o)))
This gives us, for example,
(v3 52 58 15 '(0 2 4 5 7 9))
;(53 52 52 52 55 55 55 53 52 55 53 57 52 53 57)
An idiomatic v3
An idiomatic version would use the sequence library:
(defn v3 [mi ma cnt tones]
(let [tone-set (set tones)
numbers (repeatedly #(random-number mi ma))
in-tones (filter (comp tone-set tone-class) numbers)]
(take cnt in-tones)))
This generates the sequence front first. Though you can't tell by looking at the outcome, the repaired version above generates it back to front.
An alternative idiomatic v3
Using the ->> threading macro to capture the cascade of function calls:
(defn v3 [mi ma cnt tones]
(->> (repeatedly #(random-number mi ma))
(filter (comp (set tones) tone-class))
(take cnt)))
Consider a query function q that returns, with a delay, some (let say ten) results.
Delay function:
(defn dlay [x]
(do
(Thread/sleep 1500)
x))
Query function:
(defn q [pg]
(lazy-seq
(let [a [0 1 2 3 4 5 6 7 8 9 ]]
(println "q")
(map #(+ (* pg 10) %) (dlay a)))))
Wanted behaviour:
I would like to produce an infinite lazy sequence such that when I take a value only needed computations are evaluated
Wrong but explicative example:
(drop 29 (take 30 (mapcat q (range))))
If I'm not wrong, it needs to evaluate every sequence because it really doesn't now how long the sequences will be.
How would you obtain the correct behaviour?
My attempt to correct this behaviour:
(defn getq [coll n]
(nth
(nth coll (quot n 10))
(mod n 10)))
(defn results-seq []
(let [a (map q (range))]
(map (partial getq a)
(iterate inc 0)))) ; using iterate instead of range, this way i don't have a chunked sequence
But
(drop 43 (take 44 (results-seq)))
still realizes the "unneeded" q sequences.
Now, I verified that a is lazy, iterate and map should produce lazy sequences, so the problem must be with getq. But I can't understand really how it breaks my laziness...perhaps does nth realize things while walking through a sequence? If this would be true, is there a viable alternative in this case or my solution suffers from bad design?
I wrote this code to nest a function n times and am trying to extend the code to handle a test. Once the test returns nil the loop is stopped. The output be a vector containing elements that tested true. Is it simplest to add a while loop in this case? Here is a sample of what I've written:
(defn nester [a inter f]
(loop [level inter expr a]
(if (= level 0) expr
(if (> level 0) (recur (dec level) (f expr))))))
An example input would be an integer 2, and I want to nest the inc function until the output is great than 6. The output should be [2 3 4 5 6 7].
(defn nester [a inter f test-fn]
(loop [level inter
expr a]
(if (or (zero? level)
(nil? (test-fn expr)))
expr
(recur (dec level)
(f expr)))))
If you also accept false (additionally to nil) from your test-fn, you could compose this more lazily:
(defn nester [a inter f test-fn]
(->> (iterate f a)
(take (inc inter))
(drop-while test-fn)
first))
EDIT: The above was answered to your initial question. Now that you have specified completely changed the meaning of your question:
If you want to generate a vector of all iterations of a function f over a value n with a predicate p:
(defn nester [f n p]
(->> (iterate f n)
(take-while p)
vec))
(nester inc 2 (partial > 8)) ;; predicate "until the output is greater than six"
;; translated to "as long as 8 is greater than
;; the output"
=> [2 3 4 5 6 7]
To "nest" or iterate a function over a value, Clojure has the iterate function. For example, (iterate inc 2) can be thought of as an infinite lazy list [2, (inc 2), (inc (inc 2)), (inc (inc (inc 2))) ...] (I use the [] brackets not to denote a "list"--in fact, they represent a "vector" in Clojure terms--but to avoid confusion with () which can denote a data list or an s-expression that is supposed to be a function call--iterate does not return a vector). Of course, you probably don't want an infinite list, which is where the lazy part comes in. A lazy list will only give you what you ask it for. So if you ask for the first ten elements, that's what you get:
user> (take 10 (iterate inc 2))
> (2 3 4 5 6 7 8 9 10 11)
Of course, you could try to ask for the whole list, but be prepared to either restart your REPL, or dispatch in a separate thread, because this call will never end:
user> (iterate inc 2)
> (2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
=== Shutting down REPL ===
=== Starting new REPL at C:\Users\Omnomnomri\Clojure\user ===
Clojure 1.5.0
user>
Here, I'm using clooj, and this is what it looks like when I restart my REPL. Anyways, that's all just a tangent. The point is that iterate answers the core of your question. The other part, stopping upon some test condition, involves take-while. As you might imagine, take-while is a lot like take, only instead of stopping after some number of elements, it stops upon some test condition (or in Clojure parlance, a predicate):
user> (take-while #(< % 10) (iterate inc 2))
> (2 3 4 5 6 7 8 9)
Note that take-while is exclusive with its predicate test, so that here once the value fails the test (of being less than 10), it excludes that value, and only includes the previous values in the return result. At this point, solving your example is pretty straightfoward:
user> (take-while #(< % 7) (iterate inc 2))
> (2 3 4 5 6)
And if you need it to be a vector, wrap the whole thing in a call to vec:
user> (vec (take-while #(< % 7) (iterate inc 2)))
> [2 3 4 5 6]