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 |

2007-11-06

Series (3) / generatorとgatherer

| 01:34 |  Series (3) / generatorとgatherer - わだばLisperになる を含むブックマーク はてなブックマーク -  Series (3) / generatorとgatherer - わだばLisperになる

今回は、Seriesと同じく配布されていて、また同じくCLtL2の巻末にも関連して収録されている、ジェネレータとギャザラを試してみることにしました。

generator

ジェネレータは、シリーズの列を順番に取り出す機構のようです。

(generator シリーズ)

とすると、ジェネレータが生成されます。

生成された、ジェネレータは

(next-in ジェネレータ 空になったときのアクション)

で順番に取り出すことができ、空になると、指定したアクションを実行します。

(defun doとgeneratorをつかったfizzbuzz ()
  (do ((gen (generator (scan-range :from 1 :upto 100))))
      (())
    (let* ((i (next-in gen (return)))
	   (fizz (zerop (mod i 3)))
	   (buzz (zerop (mod i 5))))
      (print (cond ((and fizz buzz) "FizzBuzz")
		   (fizz "Fizz")
		   (buzz "Buzz")
		   ('T i))))))

無理矢理な感じですが、FizzBuzzを作ってみました。doは無限ループと変数束縛のために使っています。

gatherer

ギャザラはジェネレータの逆で、

(gatherer コレクタ) ;コレクタは、collect系の関数

結果を溜め込む機構であるギャザラを生成し、

(next-out ギャザラ)

で指定したギャザラに溜め込み、溜め込んだものは、

(result-of ギャザラ)

を呼ぶことで、結果として返せます。

(defun remq (item list &key (count -1))
  (let ((res (gatherer #'collect)))
    (iterate ((l (scan list)))
      (cond ((zerop count) (next-out res l))
	    ((eq item l) (decf count))
	    ('T (next-out res l))))
    (result-of res)))

(remq 'x '(x x x x x foo x) :count 2)
;=> (X X X FOO X) 

gathererを使ってeqで要素を比較するremoveを作ってみました。

gathering

gathererは出力が一つですが、gatheringは複数を切り換え出力できるところが違い、また、本体から抜けると自動で結果が返されます。

(gathering ((変数 コレクター) (変数 コレクター)) ~本体~)
(defvar hiyoko '(♂ ♀ ♂ ♀ ♂ ♀ ♂ ♀ ♂ ♀ ♂ ♂ ♀ ♂  ♂ ♀ ♂ ♀ ♀ ♂ ♀ ♀))

(gathering ((m collect) (f (lambda (x) (collect 'vector x))))
  (iterate ((i (scan hiyoko)))
    (case i
      ((next-out m i))
      ((next-out f i)))))
=>
(♂ ♂ ♂ ♂ ♂ ♂ ♂ ♂ ♂ ♂ ♂), #(♀ ♀ ♀ ♀ ♀ ♀ ♀ ♀ ♀ ♀ ♀)

ひよこの選別をすると考えて、♂はリストで、♀はベクタの2値を返しています。