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-11

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

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

initially節とfinally節

繰り返し処理の流れとしては、

  1. 変数の初期化等の前準備
  2. 繰り返し本体
  3. 後始末

等が多いかと思いますが、LOOPでは、initiallyで、前準備の節を、finallyで後始末の節を区切ることができます。

  • :finally

後始末を:finallyキーワードの後に書くと繰り返し終了時にまとめて実行されます。

(loop :repeat 5 
      :collect (random 10) :into rs
      :collect (gensym) :into gs
      :finally (return (list rs gs)))
;=> ((5 3 3 0 6) (#:G2112 #:G2113 #:G2114 #:G2115 #:G2116))

返り値を返したい場合は、明示的に(return)する必要があります。

  • :initially

:initiallyは、他の構文で代用できることが多いためか、実際の使用例は殆ど見掛けません。

あえて、

(prog (list ans)
      (setq list '(1 2 3 4 5))
  L   (cond ((null list) (return (nreverse ans))))
      (push (* 2 (pop list)) ans)
      (go L))
;=> (2 4 6 8 10)

;; ※はるか昔のPROGでは、変数宣言と、初期化は同時にできなかった

のような古えのPROGを使った繰り返しのイディオムをそのまま移植したりするのには便利かもしれません。

(loop :with list :and ans
      :initially (setq list '(1 2 3 4 5))
      :when (null list) :return (nreverse ans)
      :do (push (* 2 (pop list)) ans))
;=> (2 4 6 8 10)