This has particularly useful when dealing with mapping functions for
variously libraries. Not sure whether this falls into the scope of Alexandria
or not, but I find myself reaching for it often enough that it would be nice to
have.
The other question is whether the plural version is really necessary or whether
the singular version could be left out in favour of the plural version.
Personally, I've only had use for the singular version.
I've attached a patch that includes docstrings and some tests, but I've placed
the implementations inline for easy perusal/discussion.
(defmacro with-collector ((name) &body forms)
(with-unique-names (list-head list-tail)
`(let* ((,list-head (list nil))
(,list-tail ,list-head))
(flet ((,name (object)
(rplacd ,list-tail (setq ,list-tail (list object)))
object))
,@forms
(cdr ,list-head)))))
(defmacro with-collectors ((&rest names) &body forms)
(let ((name-gensyms (make-gensym-list (length names))))
(labels ((%expand-collectors (names name-gensyms)
(if names
`(setf ,(car name-gensyms)
(with-collector (,(car names))
,(%expand-collectors (cdr names) (cdr
name-gensyms))))
`(progn ,@forms))))
`(let ,name-gensyms
,(%expand-collectors names name-gensyms)
(values ,@name-gensyms)))))
Basic usage is simply:
(with-collector (collect)
(dotimes (x 4)
(collect x)))
=> '(0 1 2 3)
Regards,
--
Daniel White