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 |

2008-07-06

サンプルコードによるLOOPマクロ入門 (6)

| 07:52 | サンプルコードによるLOOPマクロ入門 (6) - わだばLisperになる を含むブックマーク はてなブックマーク - サンプルコードによるLOOPマクロ入門 (6) - わだばLisperになる

ローカル変数

LOOP内ではループ内でローカル変数を宣言して使用することができます。

良く

(let ((foo 1)
      (bar 2)
      (baz 3))
  (loop :repeat 5 :collect (list foo bar baz)))

;=> ((1 2 3) (1 2 3) (1 2 3) (1 2 3) (1 2 3))

のようなコードを見かけますが、これは、

(loop :with foo := 1 :and bar := 2 :and baz := 3
      :repeat 5 :collect (list foo bar baz)))

;=> ((1 2 3) (1 2 3) (1 2 3) (1 2 3) (1 2 3))

という風に:withを使って書けます。

上の元の例の場合、foo、bar、bazはletを使って並列に束縛されているのですが、この場合、:andでつなぎます。

では、

(let* ((foo 1) 
       (bar 2)
       (baz (* 3 foo)))
  (loop :repeat 5 :collect (list foo bar baz))))

;=> ((1 2 3) (1 2 3) (1 2 3) (1 2 3) (1 2 3))

のようにlet*で順番に上から束縛する場合はどう書くかというと、

(loop :with foo := 1 :and bar := 2
      :with baz := (* 3 foo)
      :repeat 5 :collect (list foo bar baz))

;=> ((1 2 3) (1 2 3) (1 2 3) (1 2 3) (1 2 3))

と:withを複数回使って書きます。

LOOPでは、:andが文脈によって意味が変ってくるのですが、どっちがパラレルでどっちがシリアル束縛か忘れてしまったら、マクロ展開をして結果を確認するのがてっとり早いかもしれません。

まとめ

という風にLOOPマクロ内で変数宣言もできるのですが、複雑になると若干読み難くくなるところもあるかもしれません…。