for文

LISPにはfor文がない。それはループは再帰で書いた方がより柔軟だからだと思うけど、再帰で書くとコードが長くなりがち。回数が決まっているときのループくらいはfor文でやりたい気がする。Rubyのfor文みたいな感じでマクロを書いた。

;;for構文
(define-macro (for i start end . body)
  (let ((iter (gensym)))
    `(let ,iter ((,i ,start))
          (if (= ,i ,end)
              (begin ,@body)
              (begin ,@body
                     (,iter (+ ,i 1)))))))


gosh> (for i 0 4
           (format #t "~A~%" i))
0
1
2
3
4
#<undef>

衛生マクロ*1ではないので、iterに無名のシンボルを当てていることに注意。

*1:マクロは評価される前に普通のコードとして展開されるので、マクロの中で使っている変数がそのコンテキストで既に定義されていた場合に不都合が起こる(変数捕捉)。Schemeの衛生マクロは常に変数捕捉が起こらないように書けるらしい、けど構文がよく分からない。