Ben Wolfson <wolf...@gmail.com> writes:

Hi Ben,

>> However, the what's bad with the juxt approach above is that the
>> collection is iterated twice.  If somebody comes up with a version
>> that returns a vector of two lazy seqs and which iterates the input
>> collection only once, she'd get my warmest thank you, and my vote for
>> putting it into core.
>
> here's a first shot, kind of ugly but seems to work:
>
> user> (defn seqmr
>   [f g a bs]
>   (lazy-seq
>    (if (seq bs)
>      (g (f (first bs)) (seqmr f g a (rest bs)))
>      a)))
> #'user/seqmr
> user> (defn lazy-partition [p xs]
>   (seqmr (fn [x]
>            [(p x) x])
>          (fn [[t? x] r]
>            (if t?
>              [(lazy-seq (cons x (first r))) (lazy-seq (second r))]
>              [(lazy-seq (first r)) (lazy-seq (cons x (second r)))]))
>          [() ()]
>          xs))
> #'user/lazy-partition

Hey, cool, my warmest thank you! :-)

But although it iterates the seq just ones and thus applies the
predicate just once to every element, it's way slower than the juxt
approach.

user> (time (let [[e o] (lazy-partition even? (range 1000000))]
              (dorun e)
              (dorun o)))
"Elapsed time: 4806.654139 msecs"
nil

user> (time (let [[e o] ((juxt filter remove) even? (range 1000000))]
              (dorun e)
              (dorun o)))
"Elapsed time: 424.327826 msecs"
nil

Well, if the predicate becomes expensive, it'll start becoming faster,
though.

user> (time (let [[e o] (lazy-partition
                         (fn [x] (Thread/sleep 5) (even? x))
                         (range 100))]
              (dorun e)
              (dorun o)))
"Elapsed time: 513.543943 msecs"
nil

user> (time (let [[e o] ((juxt filter remove)
                         (fn [x] (Thread/sleep 5) (even? x))
                         (range 100))]
              (dorun e)
              (dorun o)))
"Elapsed time: 1025.856917 msecs"
nil

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