Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2009-11-20

KMRCLを眺める (17) for

| 23:53 | KMRCLを眺める (17) for - わだばLisperになる を含むブックマーク はてなブックマーク - KMRCLを眺める (17) for - わだばLisperになる

今日は、KMRCLのmacros.lispの中からFORです。

forという名前からしてCなどのforを真似てみたのかと思いきや、眺める限りではどうも、

(LOOP :FOR X :FROM 0 :TO 100 
      :DO ...)

のようなものを簡潔に書くためのマクロのようです。

使用例としては、

(WITH-NREVERSE (ANS)
  (FOR (X 1 50)
    (PUSH X ANS)))
;⇒ (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
;    30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50)

という感じでしょうか。

WITH-NREVERSEってなんだという感じですが、FORの周りがごちゃごちゃしないようにマクロにまとめてみました。

(DEFMACRO WITH-NREVERSE ((&REST VARS) &BODY BODY)
  `(LET (,@VARS)
     ,@BODY
     (VALUES ,@(MAPCAR (LAMBDA (X) `(NREVERSE ,X)) VARS))))

のようなものを考えていますが、余計わかりにくかったかもしれません…。

DOTIMESだと0から開始なので、開始を指定できるというのが地味に使いどころはありそうです。

FORの定義は、

(defmacro for ((var start stop) &body body)
  (let ((gstop (gensym)))
    `(do ((,var ,start (1+ ,var))
          (,gstop ,stop))
         ((> ,var ,gstop))
       ,@body)))

のような感じです。値増加のステップも指定できませんし非常にシンプルなものです。