複数のファイルストリームを開いてなんかするマクロ with-multiple-open-file

with-open-fileを何個も入れ子で書くのがめんどくさかったので

;;; nlet (Schemeのnamed-letと同じ)
(defmacro nlet (tag var-vals &body body)
  `(labels ((,tag ,(mapcar #'car var-vals) ,@body))
     (declare (optimize (speed 3))) ; for tail recursion optimization
     (,tag ,@(mapcar #'cadr var-vals))))

(defmacro with-multiple-open-file (stream-specs &body body)
  (nlet itr ((stream-specs stream-specs)
	     (product '())
	     (body body))
    (if (null stream-specs)
	product
	(itr (cdr stream-specs)
	     `(with-open-file (,@(car stream-specs))
		,(if body (cons 'progn body) product))
	     nil))))
(macroexpand-1 '(with-multiple-open-file ((f1 "/hoge/fuga" :direction :input)
					  (f2 "/hoge/mage" :direction :output))
		 (print (read f1) f2)))

=> (WITH-OPEN-FILE (F2 "/hoge/mage" :DIRECTION :OUTPUT)
     (WITH-OPEN-FILE (F1 "/hoge/fuga" :DIRECTION :INPUT)
       (PROGN (PRINT (READ F1) F2))))