JavaScriptやRubyだと、
arr.map(...).filter(...).sort(...)
のように、メソッドをつなげて書くことができます。
一方、Pythonでは、
arr = map(..., arr)
arr = filter(..., arr)
arr.sort()
のように、mapやfilterなどがlistのメソッドでないので、そのようなことができません。
なぜPythonでは、このようなメソッドを実装しなかったのでしょうか?
設計者の意図でそうなっているのでしょうか?
推測でもいいので、だれか教えてください!
実際の所が、意図や議論の結果なのか、俎上に上がってないだけなのか、先延ばしの結果なのかは知りませんが、ライブラリやWikipediaの記述を見ると、意図したものかな?と推測ですが思います。
マニュアルにも言及がありますし、ライブラリにも見受けられますが、関数型言語を参考にしたところが多々あるようです。Wikipediaには下記のように書かれています。
1.x
1994年1月、Python1.0がリリースした。主な特徴として関数型言語の基本であるラムダ計算を実装、MAP型、REDUCEなどが組み込まれている。
バージョン1.4ではCommon Lispにある機能とよく似たキーワード引数が導入された。また簡易ながら名前修飾を用いたカプセル化も実装された。2.x
2000年に公開。ガベージコレクションやUnicode、リストが導入され一躍メジャーな言語となった。多くの機能をHaskellから参考している。
以下もWikipediaより。
Pythonは言語自身の機能をできるだけ小さくおさえ、ユーザがいつも必要とする最小限の機能のみを提供するように作られている。……基本機能にないものの多くはライブラリによって提供されている。
メソッドチェーンにはメソッドの実装が必要で、それには組込型やそのスーパークラスでの実装が必要なので、組込みの部分が肥大化することになります。
もちろん、内部に組込型をもち、メソッドチェーン出来るメソッド群を持つクラスをライブラリとして作る方法もありますが、それはスマートでない(一つの見方として)というのがあります。
一方、外部関数として実装すれば、追加のライブラリへの実装で済みますし、追加の機能は追加のライブラリとしていけばよく、枯れた基本ライブラリに手を付けなくてよい利点があります。
もちろん言語仕様や実装方法で欠点を回避したり、見方を変えればスマートになったりします。
rubyは知りませんがjavascriptなら、Objectや自身のprototypeを拡張し、拡張する手段を設けて、動的にメソッドを追加してクラスを拡張しているライブラリがよくあります。
たしか、pythonでも同様の事は可能だったと思いますが、しかし、それは別のライブラリに副作用を与えるライブラリという事でもあり、たぶんpythonはそれを良しとはしない気がします。
以上と若干被りますが、小さくシンプルで重複した機能はいらないというpythonには既に関数型からもってきたモノがあり、いわば関数チェーンがあるので、わざわざメソッドチェーンはいらないのでしょう。
実際の所が、意図や議論の結果なのか、俎上に上がってないだけなのか、先延ばしの結果なのかは知りませんが、ライブラリやWikipediaの記述を見ると、意図したものかな?と推測ですが思います。
マニュアルにも言及がありますし、ライブラリにも見受けられますが、関数型言語を参考にしたところが多々あるようです。Wikipediaには下記のように書かれています。
1.x
1994年1月、Python1.0がリリースした。主な特徴として関数型言語の基本であるラムダ計算を実装、MAP型、REDUCEなどが組み込まれている。
バージョン1.4ではCommon Lispにある機能とよく似たキーワード引数が導入された。また簡易ながら名前修飾を用いたカプセル化も実装された。2.x
2000年に公開。ガベージコレクションやUnicode、リストが導入され一躍メジャーな言語となった。多くの機能をHaskellから参考している。
以下もWikipediaより。
Pythonは言語自身の機能をできるだけ小さくおさえ、ユーザがいつも必要とする最小限の機能のみを提供するように作られている。……基本機能にないものの多くはライブラリによって提供されている。
メソッドチェーンにはメソッドの実装が必要で、それには組込型やそのスーパークラスでの実装が必要なので、組込みの部分が肥大化することになります。
もちろん、内部に組込型をもち、メソッドチェーン出来るメソッド群を持つクラスをライブラリとして作る方法もありますが、それはスマートでない(一つの見方として)というのがあります。
一方、外部関数として実装すれば、追加のライブラリへの実装で済みますし、追加の機能は追加のライブラリとしていけばよく、枯れた基本ライブラリに手を付けなくてよい利点があります。
もちろん言語仕様や実装方法で欠点を回避したり、見方を変えればスマートになったりします。
rubyは知りませんがjavascriptなら、Objectや自身のprototypeを拡張し、拡張する手段を設けて、動的にメソッドを追加してクラスを拡張しているライブラリがよくあります。
たしか、pythonでも同様の事は可能だったと思いますが、しかし、それは別のライブラリに副作用を与えるライブラリという事でもあり、たぶんpythonはそれを良しとはしない気がします。
以上と若干被りますが、小さくシンプルで重複した機能はいらないというpythonには既に関数型からもってきたモノがあり、いわば関数チェーンがあるので、わざわざメソッドチェーンはいらないのでしょう。
なるほど、小さくシンプルであるためにあえて実装していない、ということですね。
これで納得しました。
回答ありがとうございました。
確かなことは知らないけれど、PythonとRubyのmap()の違いを1つ。
Pythonのmapは
>>> map(cmp, [1, 2, 3], [3, 2, 1]) [-1, 0, 1]
というように、複数の配列・リストその他をとれる。
もちろんmap()をメソッドにしても、同様のことができるように実装できる。
でもそうすると、複数の配列のどれを特別扱いするかで迷いそう。
こういうこともPythonでmar()が関数である理由の1つになっているかもしれない。
確かにそうですね。これは思いつきませんでした。
なるほど、小さくシンプルであるためにあえて実装していない、ということですね。
2012/03/02 20:14:27これで納得しました。
回答ありがとうございました。