I shouldn't have used mapc as an example. Consider instead some random, opaque, map-like function that couldn't be rewritten into an iter form. In any case, your collectors library seems interesting. Will check it out, thanks!
On Tue, Mar 13, 2018 at 4:08 PM Russ Tyndall <r...@acceleration.net> wrote: > Here are two different ways of rewriting that mapc with iter: > > `(iter top (repeat 1) (iter (for x in '(1 2 3)) (in top (collect x))))` > > `(iter (repeat 1) (appending '(1 2 3)))` > > `(iter (repeat 1) (appending (iter (for x in '(1 2 3)) (collect x))))` > > If I am using iter, I try hard to *only* use iter, as one of the reasons > for this library (for me) is to have a single syntax for iteration. > > That said, I wrote the `collectors` library to handle arbitrary collection > tasks that were not easily expressed as a straight iteration. > The collectors library binds local functions, so you can `(mapc #'collect > ...)` etc. > > https://github.com/AccelerationNet/collectors > > Cheers, > > Russ Tyndall > > On 03/13/2018 11:52 AM, Luís Oliveira wrote: > > 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 >> >> >> >