#!/usr/local/bin/sbcl --script (defmacro with-collect (collectors &body body) (let ((heads (mapcar #'(lambda (x) (gensym)) collectors)) (tails (mapcar #'(lambda (x) (gensym)) collectors))) `(let* ,(mapcan #'(lambda (he ta) `((,he nil) (,ta ,he))) heads tails) (macrolet ,(mapcar #'(lambda (co ta) `(,co (form) `(rplacd ,',ta (setq ,',ta (list ,form))))) collectors tails) ,@body) (values ,@(mapcar #'(lambda (he) `(cdr ,he)) heads))))) (print (sb-cltl2::macroexpand-all '(with-collect (acc) (do ((i 1 (1+ i))) ((> i 10)) (acc i))))) (defmacro -> (form . forms) (if (null forms) form `(-> ,(nsubst form 'it (car forms)) ,@(cdr forms)))) (defun join-string (lst sep) (-> (with-collect (acc) (acc (car lst)) (dolist (str (cdr lst)) (acc sep) (acc str))) (apply #'concatenate 'string it))) (let ((x (list "a" "b" "c" "d"))) (print (join-string x " ")))