迷える同胞たちへ
「関数型プログラミングはオブジェクト指向の正当な後継である」を書いてから1年以上たちました。
それより遥か昔、20年近く前に出た「Modern C++ Design」でも述べられているようにオブジェクト指向を学ぶ必要は無くなってますし、実際「オブジェクト指向」という言葉を見かけることも減ってきましたが、今でも、そしてこれからもプログラミングをするには「オブジェクト」と縁を切れないのも事実です。
なので、ここらで「オブジェクト」と呼ばれるアレコレの意味を整理してみたいと思います。
列挙してみると種類が多いし、内容もビギナーには難しいかもしれませんが、今後の学習の参考にしてください。
ちなみに「オブジェクトとは何か?」の結論を先に言っちゃうと
「仕組み的」な答えと「科学的」な答えと「哲学的」な答えと「言語感覚的」な答えがあります。
オブジェクトとはコンストラクタの実行結果である
いわゆるクラス・インスタンスの話です。
最近はコンストラクタ&デストラクタという用語を使わない言語もありますね。Swiftだとイニシャライザ・メソッド?
この命題には「リテラル型にはコンストラクタがない」とか反論し出すニワカ言語オタクがいそうです。
確かに「概念上はコンストラクタを持たない型がある言語」というのはいくらでも有りますが
でもね!
ここでいうコンストラクタって「メモリー領域の確保と値の代入を1まとめにした機構」であって、
言語の概念でそれを認めてなくても、こうした裏の仕組みなしにオブジェクトを成立させることは不可能ですから、この命題は常に「真」です。(逆命題は「偽」かな?)
とりあえず「先にメソッドありき」であることは覚えておいたほうが良いでしょう。
オブジェクトとは部分型を持つ代数的データ型のインスタンスである
クラス・インスタンスの「クラス」の部分をコンピュータ科学的に言い直してみました。
….で、多くの人が「見たこと無い用語だらけ」と頭を抱えている姿が目に浮かびますが、「情報科学」を専攻して「型システム」について学んだ方はご存知かと思います。つまり、そっち系の専門用語です。(というかSwiftのパターンマッチの説明等にも出てくる用語です。)
より正確には「部分型による多相性を持つ直積型代数的データ型のインスタンス」というべきでしょうか?
(正確無比な表現が自分にはわからんので専門の方 ヘルプ・プリーズ!)
実のところ、世間で語られている「オブジェクト指向プログラミング言語」の「機能」や「特徴」のほとんどは、「型システム」として全く違う用語で体系化されています。
だからこそ情報工学(の中でも特に「型システム」)を学べば「オブジェクト指向を学ぶ必要は無い」ということになります。ちなみに「関数型プログラミング」も「型システム」の範疇なので一緒に学べます。(当然難易度は高いけど)
つまりそういうことです。
まあ、1つの言語を”ほどほど”なレベルで使うだけならこの辺は知らなくて良いんですが、系統の異なる言語を複数習得したい、あるいはモダンな言語を使いこなしたいと思うなら「情報科学の型システム」について学ぶことは役立つでしょう。
オブジェクトとは仮想コンピュータである
これは前の記事でも触れしました。
哲学的な「概念」としてはこれ以上の答えはないでしょう。
「カプセル化」という単純な概念から始まり、やれ「物だ」とか「擬人化だ」とか「責務を担っている」とか、果ては「アクター指向だ」「いやエージェント指向だ」などと、オブジェクト指向の余波でオブジェクトに対する多くの「思想的、哲学的、宗教的」な解釈が巷に溢れていますが、それらのほとんどは「仮想コンピュータ」と「他の概念」の組み合わせです。
そりゃあコンピュータでできることに何らかの概念を持たせようとしているのですから当然そうなりますよね。
情報科学より思想・哲学が好きな人は意外と多く(自分もその傾向がありますが)、そうした人にとっては身も蓋もないツマラナイ答えですがヤムナシです。
オブジェクトとは目的語である
え?ジャンルが違う?
まあ、そう言わずにちょっとだけ考えてみてください。
確かにここでいう目的語というのは自然言語の文法の「主語、述語、目的語」の目的語で、英語では「subject, verb, object」のObjectです。
とはいえ文法や言語学の話をしたいわけではなく「言語感覚」を見つめ直して欲しいのです。
SVO構文は例えば「I write sentences.」という構造をしていて、ここでは”sentences”がObjectです。
いくつか例文を思い浮かべればわかると思いますが、Objectは「変化を受ける側」という性質があります。
これを言い直せば「操作対象」であり、かつ「状態を保持する」ってことです。…どうですか?ピンときませんか?普段何気に「〇〇オブジェクト」ってカタカタ混ざりで呼んでるのって大抵これです。
「メソッド・チェーン」や「モナド・チェーン」で「自身」を返すのもこの発想の延長上だったりします。
え?なんでモナドが出てくるのかって?
確かに数学的にはモナドとデータ型は全く異なる概念です。…で??…言語感覚的にはどちらも「目的語」ですが何か問題でも?
で?、結局何なのか?
話が発散して「結局どれなの〜?」とか「どれを重視すれば良いのかわから〜ん」とか思っている人も居ると思います。
その答えは残念ながら「全部」であり「ケースバイケース」です。
というのもここで挙げた答えはそれぞれ「仕組み(どう作られているか)」「数理(根拠は何か)」「理想像(どこから来てどこに向かうのか)」「言語感覚(どう使うのか)」と異なる視点で見ているからです。当然、語る文脈が変われば視点も変わってきます。
個人的には実装している時はオブジェクトのことを
言語感覚 > 仕組み(言語仕様含む) >> 数理 >> 理想像
の優先順位で、設計している時は
仕組み > 数理 > 言語感覚 >> 理想像
の優先順位で考えていることが多いです。
ただ、実装時でも感覚的な違和感が拭えない時には「理想像」について考えるスイッチが入っちゃったりするので一概には言えません。
総合的には「やりたいことが楽にできること」を目指しているので
言語感覚 > 仕組み > 理想像 > 数理
たぶん、こんな感じです。
この辺りは各自が自分なりのスタイルを見つけていけば良いと思います。
一方で学ぶ順番はわりと守って欲しくて、特にビギナーは
→ 仕組み → 言語感覚 → 数理 → 理想像 →
の順に繰り返しながら段階的に理解を深めていけば混乱が少ないはずです。
「数理」と「理想像」は難解で時間がかかるので飛ばしても構いません。
ただし、混乱したくなければ逆方向に進むのはNGです。
たとえ学びたいことが「理想像」の中にあっても循環方向は守ることをお勧めします。
まとめ
皆さんも薄々気づいていると思いますがソフトウェア工学におけるオブジェクトは複数の概念や解釈が寄り集まった怪物です。特に設計について考え始めると大きな壁(あるいは巨大な迷宮)として立ちふさがることでしょう。とは言え、個々は日々扱う「ありふれた存在」にすぎません。深淵を覗きすぎることなく少しずつ飼い慣らしていきましょう。
(結局、最後は幻想系かよ!?)