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

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

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

値の収集 その2

:collectや、:sum等で値を収集する場合、一つだけでなく複数に分散して値を格納したい時があります。

そういう時には、:collect等の後に:intoを付け変数名を指定します。

注意点としては、:intoを指定しない場合は暗黙の収集変数に値が格納され、LOOPを抜けたときにその値がLOOPの結果の値とされますが、:intoで指定した場合は、手動で値を返してやらないといけません。この場合、:finally節で指定するのが一般的なようです。また、:into以下の変数は:into節により適切に初期化されるので、手動で初期化する必要はありません。

(loop :for i :upfrom 0 :upto 10
      :collect i :into all
      :when (oddp i)
        :collect i :into odds
      :else
        :collect i :into evens
      :end
      :sum i :into sum
      :maximize i :into max
      :minimize i :into min
      :finally (return `(all => ,all odds => ,odds evens => ,evens sum => ,sum max => ,max min => ,min)))
;=>
(ALL => (0 1 2 3 4 5 6 7 8 9 10)
 ODDS => (1 3 5 7 9)
 EVENS => (0 2 4 6 8 10)
 SUM => 55
 MAX => 10
 MIN => 0)

はまりどころ

  • finallyで(return)を忘れる
(loop :for i :from 0 :to 10 :collect i :into ans
      :finally ans)
  • せっかく丁寧に収集用の変数を宣言してあげたのに怒られる
(loop :with ans := ()
      :for i :from 0 :to 10 :collect i :into ans
      :finally (return ans))
;>>> Variable ANS in INTO clause is a duplicate