うーん。Common Lisp でのそのようなマクロの例を次に示します。ただし、これは実際には良い考えであるとは言えません。でも、ここにいるのはみんな大人ですよね?
(defmacro nested-loop (control &body body)
(let ((variables ())
(lower-bounds ())
(upper-bounds ()))
(loop
:for ctl :in (reverse control)
:do (destructuring-bind (variable bound1 &optional (bound2 nil got-bound2)) ctl
(push variable variables)
(push (if got-bound2 bound1 0) lower-bounds)
(push (if got-bound2 bound2 bound1) upper-bounds)))
(labels ((recurr (vars lowers uppers)
(if (null vars)
`(progn ,@body)
`(loop
:for ,(car vars) :upfrom ,(car lowers) :to ,(car uppers)
:do ,(recurr (cdr vars) (cdr lowers) (cdr uppers))))))
(recurr variables lower-bounds upper-bounds))))
構文は提案とは少し異なります。
(nested-loop ((i 0 10) (j 15) (k 15 20))
(format t "~D ~D ~D~%" i j k))
に展開します
(loop :for i :upfrom 0 :to 10
:do (loop :for j :upfrom 0 :to 15
:do (loop :for k :upfrom 15 :to 20
:do (progn (format t "~d ~d ~d~%" i j k)))))
マクロの最初の引数は、次の形式のリストのリストです。
(variable upper-bound)
(下限 0 を暗黙指定) または
(variable lower-bound upper-bounds)
もう少し愛を加えると、次のようなものさえ持つことができます
(nested-loop ((i :upfrom 10 :below 20) (j :downfrom 100 :to 1)) ...)
loop
しかし、これらすべての機能がすでにあるのに、なぜわざわざする必要があるのでしょうか?