#:g1: loopにもっと括弧を

Posted 2020-09-27 04:38:31 GMT

以前、ANSI CL規格(INCITS 226-1994)の規格の更新について議論しているログを眺めたことがあったのですが、その中で、Jon L White氏が「loop にもっと括弧を」という意見を出していました。
この議論のログは確かウェブで参照できた筈ですが、今やまったく見付かりません。結構貴重な資料だと思いますが……。

loopをLispyに改善したものといえば、iterateだと思いますが、括弧をつけるだけなら、簡単な処理で実現できるなと思ったので試してみました。

(defmacro for (&rest body)
  `(loop 
    ,@(reduce (lambda (res b)
                (append res (->loop-clause b)))
              body
              :initial-value nil)))

(eval-when (:compile-toplevel :load-toplevel :execute) (defun ->loop-clause (xpr) (case (find (car xpr) '(let) :test #'string-equal) (let (destructuring-bind (let &rest args) xpr (declare (ignore let)) `(for ,@args))) (otherwise xpr))))

要するにloopに余計な括弧を付与するだけですが、まあまあそれっぽくなります。

(for (let i :from 0)
     (let j :from 0)
     (repeat 16)
     (if (oddp i)
         :collect i :into es)
     (collect i :into is)
     (collect j :into js)
     (finally (return (list es is js))))((1 3 5 7 9 11 13 15)
    (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)
    (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15))

loopだと:do節の後にprognを補ったりしがちですが、括弧で囲むと範囲がはっきりするので安定感があります。

(for (repeat 5)
     (do (print 'hello-world)
         (terpri)))
▻ 
▻ hello-world 
▻ 
▻ hello-world 
▻ 
▻ hello-world 
▻ 
▻ hello-world 
▻ 
▻ hello-world 
→ nil

まとめ

もうちょっと凝ったことをしようと思ったら素直にiterateを使う方が良いとは思いますが、案外上手くいっちゃってる感。
もっとも、JonL氏がいう「もっと括弧を」、というのは恐らくiterateのようなものを指しているのだとは思いますので誤解なきよう。


HTML generated by 3bmd in LispWorks Personal Edition 7.1.2

comments powered by Disqus