The history here is that Common Lisp gets reduce from APL (<a href="https://aplwiki.com/wiki/Reduce" rel="nofollow">https://aplwiki.com/wiki/Reduce</a>). It's not an attempt an ML-style fold, but a different formalism from a different lineage.
fold is a natural consequence of church lists, probably the most fundamental way of expressing the list abstraction:<p>\f \x (f a0 (f a1 (f a2 x)))<p>So fold is just applying a list (function) to 2 arguments. Or you can be helpful and make something like fold := \f \x \l l f x which is useful for binding the f and the x and applying to multiple lists (everything is Curried of course)<p>LISP is not quite based on lambda calculus, so it should be no surprise it doesn't quite get reduce(i.e. fold) right.<p>See also church numerals, which are like lists but without the elements, they also have a 'fold':<p>\f \x f (f (f x))) == 3<p>We can make trees! Which again also have a 'fold'<p>\f \x f a0 (x a1) (f a2 (x a3) (x a4))<p>And many other more exotic folding data structures.
> It then applies the function to successive pairs of sequence elements.<p>No. #'reduce may take the first pair as an optimization step, but from that point on it processes sequence elements one at a time. It passes an accumulated value and the next sequence value to the function.
>Fold is also simpler than REDUCE since it does not have any special case, making it easier to reason about its behaviour.<p>If returning the initial value when the list is empty is considered a special case (or "surprising aspect") of REDUCE, then it's the same for FOLD, no?
I don't have a running image handy, but<p><pre><code> (+) ; => 0
(*) ; => 1
</code></pre>
and<p><pre><code> (+ n) ; => n
(* n) ; => n
</code></pre>
which I expect has some bearing on the behavior of reduce in the examples given.<p>It's pretty obvious that any other function could either have or be advised to have whatever equivalent semantics are appropriate.<p>Of course<p><pre><code> (apply #'+ '(1 2 3 4 5)) ; => 15
</code></pre>
So reduce can be obviated by just letting the function take variable args too.