> (def nums (cons 2 (lazy-seq (map inc nums)))) > (def primes (cons (first nums) > (lazy-seq (->> > (rest nums) > (remove > (fn [x] > (let [dividors (take-while #(<= (* % %) x) > primes)] > (some #(= 0 (rem x %)) dividors)))))))) > > It works fine. However if I redefine nums like this > (def nums (drop 2 (range))) > > It gives me a wrong result > e.g. (take 5 primes) is (2 3 5 7 9)
I don't have a complete answer, but... Using your first version (cons and lazy-seq): user> (take 25 primes) (2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97) Using your second version (range): user> (take 25 primes) (2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 37 41 43 47 53 59 61 67 71) Notice that the range version has every odd number right up until 31, then it switches to starting to get the primes correct from there on. So now I'm suspicious. A quick look at the source for (range) and note it's doing chunking, with 32-item chunks: (defn range ... ([start end step] (lazy-seq (let [b (chunk-buffer 32) comp (if (pos? step) < >)] (loop [i start] (if (and (< (count b) 32) (comp i end)) (do (chunk-append b i) (recur (+ i step))) (chunk-cons (chunk b) (when (comp i end) (range i end step))))))))) Quite a numerical coincidence... So is it possible that the difference is in how the lazy sequences are being called on to produce their next item? Perhaps range, since it has a next one available and pre-calculated already, offers its up more willingly than your hand-rolled lazy-seq? Figuring the details of that out is beyond my limited capabilities at the moment, but it seems worth investigating. Finally, for interest in figuring out exactly what the two different behaviours are: (def right-nums (cons 2 (lazy-seq (map inc right-nums)))) (def right-primes (cons (first right-nums) (lazy-seq (->> (rest right-nums) (remove (fn [x] (let [dividors (take-while #(<= (* % %) x) right-primes)] (some #(= 0 (rem x %)) dividors)))))))) (def wrong-nums (drop 2 (range))) (def wrong-primes (cons (first wrong-nums) (lazy-seq (->> (rest wrong-nums) (remove (fn [x] (let [dividors (take-while #(<= (* % %) x) wrong-primes)] (some #(= 0 (rem x %)) dividors)))))))) (def wrong-answers (filter (fn [x] (not (some #(= x %) (take-while #(<= % x) right-primes)))) wrong-primes)) user> (take 2 wrong-answers) (9 15) user> (take 3 wrong-answers) (9 15 21) user> (take 5 wrong-answers) (9 15 21 25 27) user> (take 6 wrong-answers) <... much time passes, I get bored, Ctrl-C ...> ; Evaluation aborted. Hope this helps?! -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en