Here is an existing "sampling" clause to pull a random sample from a larger data set.  The long and short is just use a finally clause, as you would when writing a normal iterate loop.

(iterate:defmacro-clause (sampling expr &optional into var size size)
  "resevoir sample the input"
  (let ((sample (or var iterate::*result-var*)))
    (alexandria:with-unique-names (i sample-size sigil buffer row)
      `(progn
        (with ,sample)
        (with ,sample-size = (or ,size 100))
        (with ,buffer = (make-array ,sample-size :initial-element ',sigil))
        (with ,i = 0)
        (if (< ,i ,sample-size)
            (setf (aref ,buffer ,i) ,expr)
            (let ((r (random ,i)))
              (when (< r ,sample-size)
                (setf (aref ,buffer r) ,expr))))
        (incf ,i)
        (finally
         ;; convert our sample to a list, but only if we actually took the sample
         (when (plusp ,i)
           (setf ,sample
                 (iter (for ,row in-vector ,buffer)
                   (until (eq ,row ',sigil))
                   (collect ,row)))))))))

Cheers,
Russ Tyndall
Acceleration.net
On 03/13/2018 10:49 AM, Robert Goldman wrote:

I was going to define an AVERAGING collector clause for iterate, but I'm not sure how to do it. The obvious thing, it seemed to me, would be to sum the values as I go along, and count them, and then divide the sum by the count when leaving the loop.

But the examples for DEFMACRO-CLAUSE in the manual do all of their work while iterating, and there doesn't seem to be an "at-end" hook. Is the kind of thing I would like feasible, and if so, how is it to be done?

thanks!
r