2007-01-23

_ イテレータ

日本語版Wikipediaのイテレータの項 を見ていて気付いたのだけど、

また、Pythonではジェネレータ関数によって内部イテレータを作成することも出来る。

と書かれている。 それは違うだろー。 あれは外部イテレータを「内部イテレータを実装している感覚で」書ける仕組なのであって、 内部イテレータを書いている訳じゃない。 だって、generatorが返すのは実際iterator objectだもの。 forで内部イテレータ的に書けるのはあくまでsyntax sugarに過ぎない。

しかし、 英語版のIteratorの項 を見ると、そんな記述はないどころか、 内容的にかなり違うのね.. ここんところのWikipediaのポリシーが私にはよく分かってないところで、 別言語版に繋がっている項目でも、これだけ内容がかけ離れても構わないのか。 英語版はたまーに修正してあげることがあるけど、 よく分からない部分に突っ込みたくないので、 この誤りは放置しておきたい。

ところで、 以前 shinhさんが何やら書いておられた が、 機能的にというか、内部イテレータはイケてないのではないかと最近思うようになった。 操作能力が低い。

内部イテレータは次の三つのことをまとめてしまうのが良くない。

  • イテレータを進める。
  • 現在の値かイテレータの位置に対して何か呼ぶ
  • イテレータが終わるまでループする

だから複数のイテレータを一度に操作できなくなってしまうし、 イテレータにちょっと待ってもらって、また後で途中から始める、 とか簡単にはできない。

要するに、本来可分な操作群を不可分な操作にしていることが良くないのだ。 可分を不可分にすることは後からできるが、 不可分を可分にすることはできない。 だから、 外部イテレータを内部イテレータ化することはできるが、 内部イテレータを外部イテレータ化することは(そのままでは)やれない。

実のところ、これは特にイテレータに限った話とは言えない。 オブジェクト指向全般の問題だという気がする。 つまり、APIとして、どのレベルの操作を見せるべきか、 という問題である。

私は不可分な操作がAPIとして存在すべきだと思う。 可分な操作もあってよいと思うけれど(楽できるから)、 それらは不可分な操作の集合として表現されるべきだと思う。 そうでないと、後からもっと微細なコントロールが必要になったときに困ってしまうからだ。 こういう本来見せるべき操作を隠しちゃう問題を「やり過ぎ」と表現したい。

では、なぜ内部イテレータを採用している処理系が存在するのか。 何か見落としがあるのだろうか。

思い付くことの一つは、性能である。 多くの操作をまとめると仮定できることが増えるから、 より強い最適化が行えるかもしれない。

また、実装者にとってのイテレータの書き易さというのもあるかもしれない。 しかし、Pythonを見ての通り、コルーチンを使えば、 実装は内部イテレータと同じぐらい平易になる。 もちろん、コルーチンのオーバーヘッドのために性能は落ちるかもしれない。

本日のツッコミ(全1件) [ツッコミを入れる]
_ ゆきち (2007-01-23 18:01)

wikipediaについて。各言語版とも、独自に記事を書いても構わないルールになっています。なので、日本語版独自や、英語版と内容の異なる記事が書かれることは多くあります。理想的には、いちばん情報の多い記事にあわせて翻訳されるべきなのですが、現状は、そうなっていない状態です。

[]