[Gauche-devel-jp] 辞書とイテレータ

Back to archive index

Kimura Fuyuki fuyuk****@hadal*****
2003年 1月 21日 (火) 11:28:16 JST


At Sun, 19 Jan 2003 22:42:24 -1000 (HST),
Shiro Kawai <shiro****@lava*****> wrote:
> 
> キーから値へのマップを行うフレームワークに関してはずっと頭の隅に
> あったのですが、置きっぱなしで埃をかぶっていました。

おそらく、「考えているひとはたくさんいる」けど「あまり手をつけるひとが
いない」問題ではないかと。;)

> イテレータを用いて(イテレート中の辞書オブジェクトに対する)副作用の
> ある操作を行うのは、難しい問題だと思います。iteratee内の副作用に
> より、iteratorが保持している内部状態が意味のないものになる可能性
> があるからです。

あ、やっぱり…

どうしてPerlやなんかに副作用つきiterateeがないのかずっとふしぎだったん
ですよね。「原理的に無理」ならしょうがないけど、「めんどうだから(効率
悪いのはわかってるけど)みんな見て見ぬふりをしている」じゃないかと気に
なっていたのでした。

>  * APIで、渡すprocedureが5つというのはいかにも多すぎますねえ。
>    ここまで来たらメッセージでディスパッチするクロージャに
>    してしまった方がすっきりするような。
>    コレクションフレームワークとの連続性はこの際あまり重要では
>    ないでしょう。むしろ辞書フレームワークで良いものが出来たら逆に
>    コレクションフレームワークを合わせちゃったっていいし。

メッセージ渡しにするのは賛成です。ただ、自前でメッセージディスパッチす
るのはちょっとめんどうかも。

>  * 中断をどうするか。call/ccでやっても良いのだけれど、どうせ
>    iteratee内でnextを呼ばせるんだったら、いっそのこと継続渡しに
>    しちまっても良いんじゃないか。つまり、現在位置の値を取り出す
>    getメソッドを別に設けて、 nextメソッドを呼ぶこと=続きを
>    検索、ということにする。nextメソッドを呼ばなかったらそこで
>    iterationはおしまい。

賛成。カーソル移動(next)とgetは分けたほうがいいと思います(getは安価な
処理とはかぎらない)。

> というわけで、こんなのはいかが。
> 
>    call-with-iterator (dict <dictionary>) iteratee seed keys ...
> 
> で、iterateeは次のように呼ばれる:
> 
>    iteratee cursor seed
> 
> ここでcursorはprocedureであり、次のような動作をする:
> 
>    (cursor 'get)        現在のキーと値を返す。
>    (cursor 'next seed) 次にキーとマッチするエントリがあれば、
>                         iteratteeを呼び出す。その際にseedを
>                         第2引数として渡す。もうマッチするエントリが
>                         無ければseedがcall-with-iteratorの
>                         戻り値となる。
>    (cursor 'update! value) 現在のエントリの値を変更。
>    (cursor 'delete!)    現在のエントリを削除。
>    (cursor 'insert! key value)   key value ペアを辞書に追加。
>                         但し、実際の追加はcall-with-iterator
>                         を抜ける直前に行われる。追加されたエントリ
>                         に対してiterateeが呼ばれることはない。
> 
> seedは最初にiterateeが呼ばれる時はcall-with-iteratorの受け取った
> seedで、2回目以降は cursor 'next メソッドに渡された値。
> 
> cursorの呼び出しはcall-with-iteratorのdynamic extent内のみで
> 有効とする。

主要な問題は小黒さんが出してくれたので、私はわりと瑣末なところをつつい
てみます。

- get が返すキーと値はペアか多値か?

- keys は引数に並べるかたちで大丈夫か? 数が多くなったときに効率が悪く
  はないか?

- わからない/実行できないメッセージが来たらどうするか? (read only辞書
  などの場合。不定?)

- keys の順番と要素の取り出されてくる順番が同じである保証はない、でい
  いか? keys に重複があった場合は?

- 順序つき辞書に対応できるか? (Java には順序つきハッシュ?があったよ
  うな) insert! する位置は?

- <dictionary> は <collection> のサブクラスでいいか?

まあ、ここまで来たら、考えているよりやってみる手でしょうね。ためしに
ちょっと書いてみます。できたらさらしにきますので。

(ほかのひとも手があいていたら上の call-with-iterator を書いてみてもら
えるとうれしいです。私はalist-tableくらいしかやる気がないので、ツリー
なりハッシュなりネタは選びほうだい。 ;)

-- 
木村 冬樹




Gauche-devel-jp メーリングリストの案内
Back to archive index