どっかでそう発言したら、なぜか叩かれた。
Pythonはオブジェクト指向プログラミング言語である。
まず、前提として上を述べておく。Pythonは最初のリリースの時にはオブジェクト指向の機能が備わっていた。これは初期リリース後のバージョンアップでオブジェクト指向が後付けされたPerlやPHPとは大きく異なる。だが、はっきりと後付けであると主張したい。
オブジェクト指向が後付け = 「純粋なオブジェクト指向プログラミング言語」ではない
Wikipediaに「純粋なオブジェクト指向プログラミング言語(pure object-oriented language)」という概念が書かれている。Wikipedia-ja:オブジェクト指向プログラミングと[Wikipedia-en:Object-oriented programming]
(http://en.wikipedia.org/wiki/Object-oriented_programming)の両方に記載されているので見て欲しい。日本語版と英語版で微妙に定義が異なる気もしないでもないが、日本語版の方がすっきりしている。つまり、はじめからオブジェクト指向言語として設計されているかどうかで「純粋な(pure)」という言葉を用いている。
それ以外はなにになるのか?つまり、何かしらオブジェクト指向ではない言語設計に後からオブジェクト指向を追加した言語となる。「純粋なオブジェクト指向プログラミング言語」ではないということは、オブジェクト指向が 後付け であるといえる。日本語版ではそういったものを「ハイブリッド型オブジェクト指向プログラミング言語(hybrid object-oriented language)」と定義している。
残念ながら、Wikipediaでは、Pythonをオブジェクト指向プログラミング言語の一つと取り上げているにもかかわらず、「純粋な」にも「ハイブリット型」にも例としてあげていない。PythonよりもマイナーなRubyを取り上げているにもかかわらずだ。
最初のリリースの時点で備わっているからといって後付けではないと限らない。
上記のWikipediaの記事で注目すべきなのはC++が「ハイブリッド型」であることだ。C++はCにオブジェクト指向等を 後付け して拡張した言語である。もちろん、C++が最初にリリースされる時点で、C++はオブジェクト指向プログラミング言語であった。
つまり、Pythonが最初のリリースの時にオブジェクト指向であったからという理由だけで、「後付けではない」と結論づけることはできない。
注目すべきはリリース前の初期設計
鋭い読者なら、ここでC++とPythonの言語の成り立ちについて決定的な違いを指摘するだろう。C++はCの拡張という形で作られた。なので、Cにオブジェクト指向を 後付け したと主張しても問題ないのである。しかし、Pythonは何か他の言語の拡張ではない。もちろん、他の言語を参考にしたり、影響を受けたりはしているが、基になった言語が有るわけではない。一から設計された言語である。
しかし、Pythonは、初期設計段階ではオブジェクト指向は取り入れていなかったらしい。つまり、リリース前の初期ではオブジェクト指向プログラミング言語では無かった。その後、オブジェクト指向を 後付け してから、一般にリリースされたと言うことだ。この話の根拠とは言われるとRubyの作者が書いたRubyist のための他言語探訪 【第 1 回】 Pythonぐらいしかないので信憑性はあやしいと思っていたのだが、Pythonの作者自らがThe History of Python: Adding Support for User-defined Classes(和訳:The History of Python.jp: ユーザ定義クラスのサポートの追加)でその歴史的経緯を語っている。1
次に後付けである証拠であるオブジェクト指向っぽくないところを挙げていきたいと思う。
Pythonのオブジェクト指向っぽくないところ
Pythonは後付けと言ってもオブジェクト指向プログラミング言語として過不足なく使える言語である。同じく後付けのC++がオブジェクト指向プログラミング言語として十分使えるのと同じだ。なので、後付けであることをもって、オブジェクト指向には使えないという主張は 全くもってナンセンス だ。Pythonはかなり初期で綺麗に取り入れたこともあり、PerlやPHPのように後付けの仕方が汚い言語とは一線を画する。
しかしながら、はじめからオブジェクト指向プログラミング言語として設計されなかったために存在するオブジェクト指向っぽくないところもある。はじめからオブジェクト指向プログラミング言語として設計されたRubyと比較しながら見ていきたい。
関数がある
Pythonには関数がある。便利でよく使う関数(標準出力に文字を出力するprint()
関数や、配列などの長さを求めるlen()
関数など)は組み込みではじめから用意されている。関数は何かしらのオブジェクトに関連づけられたメソッドではないため、オブジェクト指向ではないところだ。
逆に、Rubyには関数がなくメソッドしかない。Rubyは暗黙のトップレベルオブジェクトmainの存在やself
を省略できるという言語設計のため、Kernel#puts
メソッドなどは関数っぽく書くことができるが、厳密にはself
(コードのトップレベルの場合は、トップレベルオブジェクトmainになる)のメソッドを呼び出しているにすぎない。
制限がある旧スタイルクラスがあった
Pythonのクラスには2種類のタイプがあった。2.1以前に使われていた旧スタイルクラスと、2.2から使えるようになった新スタイルクラスだ。旧スタイルクラスでは、組み込み型を継承できない、型とクラスの管理が別々(二つの無関係のクラスのオブジェクトa
とb
について、type(a) == type(b)
が真になる場合がある)などの問題点がいくつかあり、言語全体としてオブジェクト指向っぽくないところがあった。新スタイルクラスでは一からクラスを設計しなおし(でも書き方はほぼ変わらないというすばらしさ)、オブジェクト指向として満足するものになっている。
なお、Python3では新スタイルクラスのみになり、旧スタイルクラスは廃止された。
逆に、Rubyは型はクラスしか存在しないし、どのクラスも同じ扱いなので継承できない組み込み型(クラス)なんてものも存在しなかった。
やはりPythonはオブジェクト指向プログラミング言語であるが、それだけではない。
Pythonは長く拡張され続けたため、言語としてあまり綺麗とは言いがたい部分も出てきていた。Python3でそういった部分を整理しており、Python3は素晴らしい言語であると言える。オブジェクト指向プログラミング言語として見た場合も、新スタイルクラス一本に統合されたこともあって、「純粋なオブジェクト指向プログラミング言語」と遜色ない機能、エレガントさを備えている。
最後に少々古いがこの記事を紹介したい。
methaneのブログ:len が py3k でも 関数のままである理由
つまり、Pythonにとってオブジェクト指向プログラミング言語であることは重要では無い。もちろん「オブジェクト指向プログラミングができる」ことは重要ではあるが、言語自体がオブジェクト指向に縛られる必要は無いと考えられている。Pythonはコーディングを縛るといイメージがあるが、実はオブジェクト指向に縛られない自由な言語なのである。
Rubyは「純粋なオブジェクト指向プログラミング言語」であるが故に、オブジェクト指向に縛られたプログラミングしかできない(無理矢理することはできるが、あえてRubyを使う利点はほぼ無い)。Perlの自由さを引き継いでいるのはRubyだと思われがちだが、オブジェクト指向の束縛からは逃れられないのは皮肉なのかもしれない。
-
thanks: @shibukawa さん ↩