まつもと ゆきひろです

In message "Re: [ruby-dev:39299] Re: Why doesn't Array#product return Enumerator?"
    on Thu, 10 Sep 2009 23:52:44 +0900, Yusuke ENDOH <mame / tsg.ne.jp> writes:

|う、本当に聞きたかったのは「なんで product だけ permutation
|たちと違うインターフェイスになっているのか」です。

すでに述べた通り、「productという単語は積を返すことを期待さ
せるが、その表現としてEnumeratorは適切でないように思える」と
いうものです。また、それに対して「combinationやpermutationだっ
て同様だ」という反論は当然ありえると認識しています。

本当はcombinationなども配列を返したかったので、今の状態が理
想でないのは認めます。この辺を見落としていたのは痛い失敗です。

|あと、巨大な積を each したい場合に「便利」です。そういう場合は
|パズルを解く場合や総当りテストをする場合にそこそこ発生します。
|いきなり配列を返すのだと、each し始める前に巨大な配列が確保
|されてしまいます。product がブロックを受け取ってくれればこの
|問題はなくなります。従来どおり配列がほしいなら .to_a するだけ
|でできます。

|今だって「積」というものではなく配列を返しているのですが、
|配列はよくても Enumerator はダメなんでしょうか。

配列と配列の積の自然な型は配列なんじゃないでしょうか。to_aす
ればよいとはおっしゃいますが、概念的に違うものを返すことを積
極的に推奨するには抵抗があります。積ではなく、要素の組み合わ
せの列を返すと考えればよいのでしょうが。それとも私が理解して
ないだけで、配列の積ってそういうもの?

で、提案するのは

(1) productがブロックを取るようにする。戻り値は配列のまま。

です。ブロックを取るメソッドが取らない時にEnumeratorでなく配
列を返すのは他と違うと思われそうですが、もともとのルールは
「ブロックを取らないとエラーになっていたメソッドはEnumerator
を返す」というものだったので、少なくともルール違反ではありま
せん。

ついでに

(2) combinationとpermutationもブロックがなければ配列を返すよ
    うにする

も提案したいところですが、こちらは非互換なんで、すぐにという
わけにはいかないかもしれません。

別案としては

(3) LazyArrayのようなものを作って、product(とcombinationと
    permutation)がブロックが与えられない時には、それを返すよ
    うにする。

というのも考えられますが、よりおおげさですね。

                                まつもと ゆきひろ /:|)