日本語版Wikipediaのイテレータの項 を見ていて気付いたのだけど、
また、Pythonではジェネレータ関数によって内部イテレータを作成することも出来る。
と書かれている。 それは違うだろー。 あれは外部イテレータを「内部イテレータを実装している感覚で」書ける仕組なのであって、 内部イテレータを書いている訳じゃない。 だって、generatorが返すのは実際iterator objectだもの。 forで内部イテレータ的に書けるのはあくまでsyntax sugarに過ぎない。
しかし、 英語版のIteratorの項 を見ると、そんな記述はないどころか、 内容的にかなり違うのね.. ここんところのWikipediaのポリシーが私にはよく分かってないところで、 別言語版に繋がっている項目でも、これだけ内容がかけ離れても構わないのか。 英語版はたまーに修正してあげることがあるけど、 よく分からない部分に突っ込みたくないので、 この誤りは放置しておきたい。
ところで、 以前 shinhさんが何やら書いておられた が、 機能的にというか、内部イテレータはイケてないのではないかと最近思うようになった。 操作能力が低い。
内部イテレータは次の三つのことをまとめてしまうのが良くない。
だから複数のイテレータを一度に操作できなくなってしまうし、 イテレータにちょっと待ってもらって、また後で途中から始める、 とか簡単にはできない。
要するに、本来可分な操作群を不可分な操作にしていることが良くないのだ。 可分を不可分にすることは後からできるが、 不可分を可分にすることはできない。 だから、 外部イテレータを内部イテレータ化することはできるが、 内部イテレータを外部イテレータ化することは(そのままでは)やれない。
実のところ、これは特にイテレータに限った話とは言えない。 オブジェクト指向全般の問題だという気がする。 つまり、APIとして、どのレベルの操作を見せるべきか、 という問題である。
私は不可分な操作がAPIとして存在すべきだと思う。 可分な操作もあってよいと思うけれど(楽できるから)、 それらは不可分な操作の集合として表現されるべきだと思う。 そうでないと、後からもっと微細なコントロールが必要になったときに困ってしまうからだ。 こういう本来見せるべき操作を隠しちゃう問題を「やり過ぎ」と表現したい。
では、なぜ内部イテレータを採用している処理系が存在するのか。 何か見落としがあるのだろうか。
思い付くことの一つは、性能である。 多くの操作をまとめると仮定できることが増えるから、 より強い最適化が行えるかもしれない。
また、実装者にとってのイテレータの書き易さというのもあるかもしれない。 しかし、Pythonを見ての通り、コルーチンを使えば、 実装は内部イテレータと同じぐらい平易になる。 もちろん、コルーチンのオーバーヘッドのために性能は落ちるかもしれない。
wikipediaについて。各言語版とも、独自に記事を書いても構わないルールになっています。なので、日本語版独自や、英語版と内容の異なる記事が書かれることは多くあります。理想的には、いちばん情報の多い記事にあわせて翻訳されるべきなのですが、現状は、そうなっていない状態です。