# Re: Defining AVERAGING clause

```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
>
>
>
```