From: matz@... (Yukihiro Matsumoto) Date: 2002-11-22T03:57:30+09:00 Subject: [ruby-dev:18891] Re: internal/external iterator (Re: Re: Enumerable#zip) まつもと ゆきひろです In message "[ruby-dev:18890] internal/external iterator (Re: Re: Enumerable#zip)" on 02/11/22, Tanaka Akira writes: | |In article <1037884596.418916.10540.nullmailer@picachu.netlab.jp>, | matz@ruby-lang.org (Yukihiro Matsumoto) writes: | |> |内部イテレータと呼べるかどうかは、何を「イテレータ」と見るかによ |> |るんじゃないでしょうか? | |GoF 本のあの文脈における「イテレータ」というのはは外部イテレータの場合 |は Iterator クラス(ないしそれ以下のクラス階層)、内部イテレータの場合は |ブロックやクロージャを受け取るメソッドを指しているように思えます。 | |いずれにしても、制御を抽象化するコードを書く部分をイテレータと呼んでい |るのでしょう。 ま、同意します。が、「外部イテレータ」と呼ばれているものは 「要素の繰り返し」しか考えていないように見えるのに対して、 「内部イテレータ」と呼ばれているものはRubyの(Smalltalkの) collect, select, detectのように単なる要素の繰り返しを越えて より抽象度の高い使われ方をするように思います。 内部・外部という名前が適切でないという点は同意するとして、実 は最終的にはここが一番重要な違いだったりして。 この観点からは提案されているC#のイテレータは(1種類しか定義で きないので)外部イテレータ的ですね。Pythonのは...うーん、どう だろう。collect, select, detectは素直には書けないような。 Pythonのyieldは値を帰しませんよね。 |generator.rb は外部イテレータのふりをした内部イテレータを実現する? あえて言えばgenerator.rbは「内部イテレータを利用して外部イテ レータを実装する」でしょう。 |なんというか、外部と内部という名前がなんの意味もない気がするんですけど。 |foo と bar に置き換えてもいいというか、どこがどう内部なんですかと尋ね |たくなるというか。 うーん、Pythonのはgeneratorだからイテレータではない(ので、外 部・内部の分類の対象ではない)という論法はありえますよね。苦 しいけど。C#のは...もっと苦しいなあ。^^;;; えーと、ここまでの考察から得られる結論は * 内部イテレータ・外部イテレータという分類はSmalltalkとC++ という限定した「繰り返し機能」についてしか有効ではない (ような気がする)。 * Rubyのは(Smalltalk的)内部イテレータと呼んでも問題はない。 実質的に大差ないから。 * でもPythonのgeneratorや将来のC#のイテレータに関してはイ テレータの内部・外部の分類には意味がない(のかなあ)。しか し、発想としては外部イテレータに近い気がする。 呼び出し側はfor(foreach)文でイテレータ(ジェネレータ)オブ ジェクトの生成と個々の要素の取り出しを隠蔽していますが、 これはマクロによる隠蔽と大差ないし、定義側もブロックやク ロージャを受けているわけではないので、結局は要素を個別に 与えるくらいしか出来ないし。 てなことなんでしょうか。 まつもと ゆきひろ /:|)