简体   繁体   中英

Where am I losing lazyness?

I am attempting to program a lazy iterative prime sieve.

Each iteration of the sieve is represented by

[[primes] (candidates) {priority-map-of-multiples-of-primes}]

and I have a function, sieve-next-candidate-update, that merrily takes a sieve iteration, checks the next candidate, and updates all three components appropriately.

Used like this:

(take 3 (iterate sieve-next-candidate-update [[2] (range 3 13 2) (priority-map 2 2)]))

I get the results I expect:

([[2] (3 5 7 9 11) {2 2}]
 [[2 3] (5 7 9 11) {3 3, 2 4}]
 [[2 3 5] (7 9 11) {5 5, 2 6, 3 6}])

However, when I run it through a reduce to remove the iterations that do not find a new prime, it attempts to process the entire sequence however I define the initial candidates list (apparent infinite loop if I use iterate).

(take 3 
   (reduce (fn [old-primes-sieves new-sieve]
             (prn (str "reduce fn called with new sieve" new-sieve))
             (if (= (last (first (last old-primes-sieves))) ; I'm aware I don't want last in the final version
                    (last (first new-sieve)))
               old-primes-sieves
               (conj old-primes-sieves new-sieve)))
           []
           (iterate sieve-next-candidate-update [[2] (range 3 13 2) (priority-map 2 2)])))

outputs

"reduce fn called with new sieve[[2] (3 5 7 9 11) {2 2}]"
"reduce fn called with new sieve[[2 3] (5 7 9 11) {3 3, 2 4}]"
"reduce fn called with new sieve[[2 3 5] (7 9 11) {5 5, 2 6, 3 6}]"
"reduce fn called with new sieve[[2 3 5 7] (9 11) {7 7, 2 8, 3 9, 5 10}]"
"reduce fn called with new sieve[[2 3 5 7] (11) {3 9, 2 10, 5 10, 7 14}]"
"reduce fn called with new sieve[[2 3 5 7 11] nil {11 11, 2 12, 3 12, 7 14, 5 15}]"

and then throws a NullPointerException in this limited case.

Where am I losing lazyness?

reduce is not lazy - it will try to iterate whole infinite sequence (iterate sieve-next-candidate-update [[2] (range 3 13 2) (priority-map 2 2)]) . You can use reductions instead.

By the way, nice example of efficient infinite prime numbers sequence can be found in clojure.contrib here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM