The Kitchen Sink and Other Oddities

Atabey Kaygun

Reduce with Intermediate Results in Common Lisp

Description of the problem

It has been a while since I wrote lisp code. Today, I am going to write a reduce that returns its intermediate results. The solution I present here is shorter than the solution presented on StackOverflow. Clojure already has a function called reductions that does the same thing, but I wanted to implement my own version in Common Lisp.

Implementation

So, here it goes…

(defun reduce-with-intermediates (fn xs &optional carry)
  (if (null xs)
      (nreverse carry)
      (let ((res (if (null carry)
                     (funcall fn (car xs))
                     (funcall fn (car xs) (car carry)))))
        (reduce-with-intermediates fn (cdr xs) (cons res carry)))))
REDUCE-WITH-INTERMEDIATES

Test

Let us test it on a simple example:

(reduce-with-intermediates #'+ '(1 2 3 4 5))
(1 3 6 10 15)

Here is a more complicated but an interesting example:

(reduce-with-intermediates (lambda (x &optional y) (append y (list x))) '(1 2 3 4))
((1) (1 2) (1 2 3) (1 2 3 4))