(defn my-reductions
([f coll]
(if (seq coll)
(cons (first coll) (my-reductions f (first coll) (rest coll)))
(cons (f) nil)))
([f acc coll]
(if (seq coll)
(let [nextval (f acc (first coll))]
(lazy-seq (cons nextval (my-reductions f nextval (rest
coll))))))))
On the plus side, it appears to be faster (as collections grow large),
and it doesn't "cheat" by introducing an atom. On the minus side it
isn't as pretty as the one in contrib.
Stu
2009/8/6 Stuart Halloway <stuart....@gmail.com>:
>
> On the plus side, it appears to be faster (as collections grow large),
> and it doesn't "cheat" by introducing an atom. On the minus side it
> isn't as pretty as the one in contrib.
While maybe not as pretty as the one in contrib, it's not a monster
either. Shouldn't we aim for efficiency rather than elegance in
library routines (within reason)? I think the user will appreciate the
speedy version more than the pretty version. Since this change retains
the original interface, I would say go for it.
I'm a bit confused by the (cons (f) nil) form in the else clause. It
is going to fail unless f is of 0 arity. If f is of arity 2 we get an
IllegalArgumentException from eval. So wouldn't it be more correct to
return an empty list?
> Stu
--
! Lauri
This is the difference between FreeBSD and NetBSD. I agree, but I also
find it useful to crack open core and contrib to see coding examples
and to understand algorithms. It's a balancing act. I'm definitely for
this change though. I use reductions from time to time.
—
Daniel Lyons
Good call, the version in contrib predates lazy-seq and full laziness.
You can see the challenges faced in its implementation (back in the
lazy-cons days) here:
But, the version you have isn't fully lazy either. As a general rule,
lazy-seq should wrap the entire body:
(defn reductions
([f coll]
(lazy-seq
(if (seq coll)
(cons (first coll) (reductions f (first coll) (rest coll)))
(cons (f) nil))))
([f acc coll]
(lazy-seq
(if (seq coll)
(let [nextval (f acc (first coll))]
(cons nextval (reductions f nextval (rest coll))))))))
Rich