Just a curiosity: you could compute the average incrementally: < https://math.stackexchange.com/questions/106700/incremental-averageing>, but doing it the usual way is probably more efficient and with smaller numeric error when using floats.
Slightly off-topic question: oftentimes I have to use map-like iterators. Is there a good way to use such iterators in conjunction with iter? An obvious way would be something like: (iter (repeat 1) (mapc (lambda (x) (collect x)) '(1 2 3))) The (iter (repeat 1) ...) bit could be hidden under a macro, I suppose. But it'd be nicer if collect were a function, so I could do (mapc #'collect '(1 2 3)). Perhaps said macro could rewrite #'clause to (lambda (x) (expansion-of-clause x)) or something similar. Looks like a fun idea to explore so I'm wondering if someone's played with something like this before. (It's even more fun to turn map-like iterators into generators using continuations, but that's fully off-topic. :-)) Cheers, Luís On Tue, Mar 13, 2018 at 3:08 PM Russ Tyndall <r...@acceleration.net> wrote: > 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 > > >