Alan Malloy <a...@malloys.org> writes:

> On Aug 26, 12:40 pm, Tassilo Horn <tass...@member.fsf.org> wrote:
>> Paul  Mooser <taron...@gmail.com> writes:
>>
>> Hi Paul,
>>
>> > If you search for "filter" and "StackOverflowError" in this group, you
>> > will find people discussing related issues.
>>
>> Thanks, I've found some explanation by Meikel Brandmeier who explains
>> the layering issue.  But do we really have to live with that?
>>
>> I mean, replacing the filter/remove with a list comprehension solved the
>> issue for me.  And it's easy to define filter in terms of for.
>>
>> --8<---------------cut here---------------start------------->8---
>> user> (defn philter [pred coll]
>>         (for [x coll :when (pred x)] x))
>> #'user/philter
>> user> (filter even? (take 10 (iterate inc 0)))
>> (0 2 4 6 8)
>> user> (philter even? (take 10 (iterate inc 0)))
>> (0 2 4 6 8)
>> --8<---------------cut here---------------end--------------->8---
>>
>> I've tried benchmarking filter vs. philter with seqs of different sizes,
>> and there seems to be no difference.  So why not simply do it that way?
>
> It would make no difference. philter is exactly as lazy as filter, and
> will have the same stacked-laziness problem. See
> http://stackoverflow.com/questions/2946764/recursive-function-causing-a-stack-overflow
> which in my opinion is a pretty clear presentation of the problem.

Yes, I've read that.  But in the qsort implementation, replacing
filter/remove with for did the trick.

Using the code from the linked article, I found out that although the
StackOverflowError will eventually occur, using philter pushes the limit
at least a bit:

--8<---------------cut here---------------start------------->8---
(defn philter [pred coll]
  (for [x coll :when (pred x)] x))

(defn sieve [potentials primes]
  (if-let [p (first potentials)]
    (recur (filter #(not= (mod % p) 0) potentials) (conj primes p))
    primes))

(defn sieve2 [potentials primes]
  (if-let [p (first potentials)]
    (recur (philter #(not= (mod % p) 0) potentials) (conj primes p))
    primes))

user> (do (sieve (range 2 29000) []) nil)
; StackOverflowError
user> (do (sieve2 (range 2 29000) []) nil)
nil
user> (do (sieve2 (range 2 32000) []) nil)
nil
user> (do (sieve2 (range 2 33000) []) nil)
; StackOverflowError
--8<---------------cut here---------------end--------------->8---

Bye,
Tassilo

-- 
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

Reply via email to