I have been bitten by this `thunk` overflow many times in Haskell but 
rarely in Clojure

Just to play with sieve (no optimization, just test and play with 
functions),
I have tried to pile up function calls, but of course recursion of 
unrelated functions usually ends with a stackoverflow (trampoline seems 
hard to use in this case).

(defn siev1 [i n pred]
  (if (> i (/ n 2))
    (remove pred (range 2 (inc n)))
    (recur (inc i) n (fn [x]
                       (or (pred x)
                         (and (> x i) (zero? (rem x i))))))))

(last (siev1 2 50000 (fn [x] false)))    ;; stackoverflow


But if jvm can't keep all in a stack, why not use a vector to keep 
predicates in the heap 

(defn some-p [preds x]
  (when-let [pred (first preds)]
    (if (pred x) x (recur (next preds) x))))

(defn siev2 [i n preds]
  (if (> i (/ n 2))
    (remove #(some-p preds %) (range 2 (inc n)))
    (recur (inc i) n (conj preds #(and (> % i) (zero? (rem % i)))))))

(last (siev2 2 50000 []))
49999

Clojure is always fun to play
and I have not even try reducers yet :)

-
kawas

Le jeudi 5 septembre 2013 09:01:01 UTC+2, Cedric Greevey a écrit :
>
> Deeply nested lazy seq generation? Try wrapping the main sequence in a 
> doall at each iteration of the outer loop.
>
>
> On Wed, Sep 4, 2013 at 11:53 PM, John Gabriele <jmg...@gmail.com<javascript:>
> > wrote:
>
>> I tried implementing the sieve of Eratosthenes in Clojure. The approach 
>> is to loop while (A) keeping my current list of numbers which have not yet 
>> been eliminated, and (B) keeping track of the number I'm "on" (checking for 
>> multiples thereof).
>>
>> Here's what I came up with (in a foo.clj file):
>>
>> ~~~clojure
>> (declare remove-multiples-of)
>> (declare next-one-after)
>>
>> (defn main
>>   [max-num]
>>   (let [starting-nums (range 2 max-num)]
>>     (loop [new-nums (remove-multiples-of 2 starting-nums)
>>            new-num  (next-one-after 2 new-nums)]
>>       (if (or (nil? new-num)
>>               (> new-num (* 0.5 max-num)))
>>         new-nums
>>         (recur (remove-multiples-of new-num new-nums)
>>                (next-one-after new-num new-nums))))))
>>
>> (defn remove-multiples-of
>>   "Removes all multiples of n (but not $n * 1$) from xs."
>>   [n xs]
>>   (remove (fn [x] (and (> x n)
>>                        (zero? (rem x n))))
>>           xs))
>>
>> (defn next-one-after
>>   "It's assumed that xs is an ordered sequential collection of positive
>> integers, and that n is among xs. Returns the element right after n, 
>> unless
>> n is the last element --- if that's the case, just returns nil."
>>   [n xs]
>>   (second (drop-while (fn [x]
>>                         (not= x n))
>>                       xs)))
>>
>> ;;---------------------------
>> (println (last (main 5000)))
>> ~~~
>>
>> Running that (via `lein exec foo.clj`), it appears to work.
>>
>> However, if I change that 5000 to 50000, I get a long 
>> disapproving-looking stack trace starting with 
>> java.lang.StackOverflowError. Why is it overflowing?
>>
>> Thanks!
>>
>>  -- 
>> -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@googlegroups.com<javascript:>
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+u...@googlegroups.com <javascript:>
>> 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 unsubscribe from this group and stop receiving emails from it, send an 
>> email to clojure+u...@googlegroups.com <javascript:>.
>> For more options, visit https://groups.google.com/groups/opt_out.
>>
>
>

-- 
-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to