When a var's definition has a "lazy reference" to itself, as primes does below, then your results will be dependent on the lazy/chunky/strict-ness of the calls leading to the lazy reference.
The functions range, rest, and remove are chunk-aware, so the range-based version of primes consumes a bunch of numbers before its changes become self-visible. Other functions, such as iterate, are not chunked, so the results are visible to primes sooner. In most domains it is rare to have definitions with *this* kind of self-reference. When you do have it, your best bet is to take explicit control over the laziness by using recur and/or lazy-seq directly. The example below (simplified from contrib) demonstrates this approach to primes: (def primes (concat [2] (let [primes-from (fn primes-from [n] (if (some #(zero? (rem n %)) (take-while #(<= (* % %) n) primes)) (recur (+ n 2)) (lazy-seq (cons n (primes-from (+ n 2))))))] (primes-from 2)))) This approach also saves memory over having a separate nums collection--nums is fully (and unnecessarily) realized in memory in the implementations below. Hope this helps, Stu > Hi, > I tried experimenting with lazy sequences and wrote this program > > (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 see how that can be. > I put in a println to see where the problem is > I inserted this line before the "some" function call. > (println (str "x = " x ", dividors = " (seq dividors))) > If I then define nums as (drop 2 (range)) > and write (take 5 primes) I get this output > > (x = 3, dividors = > x = 4, dividors = (2) > x = 5, dividors = (2) > x = 6, dividors = (2) > x = 7, dividors = (2) > x = 8, dividors = (2) > x = 9, dividors = (2) > x = 10, dividors = (2) > x = 11, dividors = (2) > x = 12, dividors = (2) > x = 13, dividors = (2) > x = 14, dividors = (2) > x = 15, dividors = (2) > x = 16, dividors = (2) > x = 17, dividors = (2) > x = 18, dividors = (2) > x = 19, dividors = (2) > x = 20, dividors = (2) > x = 21, dividors = (2) > x = 22, dividors = (2) > x = 23, dividors = (2) > x = 24, dividors = (2) > x = 25, dividors = (2) > x = 26, dividors = (2) > x = 27, dividors = (2) > x = 28, dividors = (2) > x = 29, dividors = (2) > x = 30, dividors = (2) > x = 31, dividors = (2) > 2 3 5 7 9) > > That just doesn't make any sense. Can anyone explain this? > > btw, I use clojure 1.2.0 > > -- > 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 -- 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