Function: MAKE-REDUCER

Documentation

Create a function which, starting with INITIAL-VALUE, reduces any other values into a single final value. FUNCTION will be called with two values: the current value and the new value, in that order. FUNCTION should return exactly one value. The reducing function can be called with n arguments which will be applied to FUNCTION one after the other (left to right) and will return the new value. If the reducing function is called with no arguments it will return the current value. Example: (setf r (make-reducer #'+ 5)) (funcall r 0) => 5 (funcall r 1 2) => 8 (funcall r) => 8

Source

(defun make-reducer (function &optional (initial-value nil initial-value-p))
  "Create a function which, starting with INITIAL-VALUE, reduces
any other values into a single final value.

FUNCTION will be called with two values: the current value and
the new value, in that order. FUNCTION should return exactly one
value.

The reducing function can be called with n arguments which will
be applied to FUNCTION one after the other (left to right) and
will return the new value.

If the reducing function is called with no arguments it will
return the current value.

Example:

 (setf r (make-reducer #'+ 5))
 (funcall r 0) => 5
 (funcall r 1 2) => 8
 (funcall r) => 8"
  (let ((value initial-value))
    (lambda (&rest next)
      (when next
        ;; supplied a value, reduce
        (if initial-value-p
            ;; have a value to test against
            (dolist (n next)
              (setf value (funcall function value n)))
            ;; nothing to test againts yet
            (setf initial-value-p t
                  value next)))
      ;; didn't supply a value, return the current value
      value)))
Source Context