コンテンツにスキップ

OOP との出会い

執筆日: 26.09.19

すごーーく、久しぶりに真面目にコードを書いている。 実験データの解析やシミュレーターの実装以外では、ほとんど一年ぶりくらいなのではないだろうか。 データ解析と言っても、もう何年も実験をやっていると、取るデータは似通っているし、解析の手順もほとんど同じなので、解析コードはほとんど使い回しで、コードを書いているというよりか、炊飯器のボタンを押しているような感覚に近い。

それ以外のコーディングも全くやっていなかったわけではないが、基本的に仕様だけ決めて AI に丸投げだったので、あんまりコードを書いている感覚はなかった。 本当はよくないんだろうが、実装していたのは研究室内の web アプリで、別にどこかに納品するわけでもないコードなので、動けばいいや精神である程度済ませていた。

そんなことをしていたら、最初は割と単純だったロジックが、色んな要望を受けることで複雑化していき、軽い気持ちでちょっと直そうかなと思ってエディタを開くと、もはやどこから手を付ければいいか分からない状態になっていた。 そして、仕方ない、久しぶりにコードを読むか、と好きでもない JavaScript のコードを読み始めた。

コードを読み始めると、もうとにかく読みにくい。 他人のコードを読むときに感じる読みにくさとは少し違って、そもそも会話が噛み合っていないような感覚に近い。 JS だからか? でもなんか違う気がした。

原因は自分が OOP (オブジェクト指向プログラミング) で書かれていないコードを受け付けづらいからだと気づいた。 そして、全ての実装を OOP 風に書きなおす作業が始まると、あら不思議。 ずっと連休初日に私を襲っていた謎の頭痛が、みるみるうちに消えていった。

OOP をちゃんと学ぼうと思ったのは、今から6年前くらいのことだ。 当時のアルバイトで Android アプリの PoC を作ることになり、それまで書いたことがなかった Java を勉強することになった。 何となく自分は本を読みながら勉強すると記憶の定着が良いことがわかっていたので、Java の入門書を買ってきて、コロナ禍だったので家に引きこもって物理の勉強などせず、Java の勉強をしていた1。

この引きこもり生活で感じたことは、Java の勉強をするというのは、OOP を学ぶことと同義であるということだ。 理由は簡単で、Java は OOP がベースにある言語だからだ。 別に OOP をしないと Java が書けないわけではないが、OOP をすることが自然になるように設計されているとは思う。

OOP そのものは Java を学ぶ前から知っているものではあった。 元々本格的にコードを書き始めたときの最初の言語は Python だったので、Python でも OOP 的な書き方はよくしていた。 今の状態は知らないが、当時は「オブジェクト指向をわかりやすく説明してみる」みたいな Qiita の記事が乱立していて、OOP 解説系というジャンルが成立していた時期だった。 そういった記事を眺めながら、ふーん、なんかそういう感じで書くと、個人的に読みやすいな程度にしか思っていなかった。

そんななんちゃって OOP の状態で Java を勉強していると、インターフェースという Python にはない概念に出会った。 そのときに、頭の何かがカチッとはまるような感覚があった。 そして、これは美しい、と思った。

その瞬間に私の中でプログラミングは、コンピュータへの命令を書く行為というよりかは、まるで自分の数学理論を作るかのような感覚に変わった2。 これはおそらく高校までの数学から、大学での学問としての数学、特に集合論を学び始めたときの感覚に近い(私はこのことをきっかけに集合論を勉強し始めたが)。

Java におけるインターフェースは、雑に言えばメソッドのシグネチャの集合である。 メソッドは与えられた入力に対して出力を返す演算であり、シグネチャはその演算の入出力の定義である。 なぜクラスよりもインターフェースに感銘を受けたかの理由はよくわからないが、おそらくこのときまでは、クラスはオブジェクトの設計図であり、データと演算をひとまとまりで管理しているもの、という認識が強かったのだと思う。 この認識は幾分実用的で、なんか名前空間が荒れてきたなと思ったときに、クラスを作ってその中に変数や関数をまとめる、というような使い方が出来るからである。 しかし、インターフェースはそもそも(default メソッド等を除いて)実装を持たないし、そんな名前空間の整理という目的では使えない。

抽象クラスとどちらを使うのか、みたいな議論も度々見かけたが、個人的に一番重要な違いは、インターフェースは多重継承できる一方で、抽象クラスは多重継承できないという点だと思う。 この制約そのものが本質的とは言わないが、自分の中で1つの数学的アナロジーを閃かせるきっかけを与えてくれた。

かなり粗い話だが、ここからは少し数学の話を考えてみよう。 ここでは実数という集合と、線形空間を比べてみたい。 実数の元は例えば 1, 1.2, -3 などのよく見かける数値で、加法(いわゆる足し算)という演算が定義できる。 一方で、線形空間の元はベクトルで、高校生にも馴染み深い数ベクトルは、例えば (1, 2), (3, 4), (-1, 0) のような列として表され、ベクトル同士の加法は n 番目 (n = 1, 2) の要素を足し合わせることで定義される。 初めてベクトルに出会ったときの感覚としては、実数とは全く別の数学的対象に見えるし、同じ根から生えているとは思えない。 しかし、実数と線形空間は、加法という演算の定義は共有している。 ここでいう加法というものを、インターフェース内で定義された抽象メソッドだと思えば、実数と線形空間は同じインターフェースを実装していることになる。 これがインターフェースの概念を初めて見たときの感覚だった3。

こういうことを考えながら、プログラミングを作った人は、とても数学的な思考をする人なのだろうなと思ったし、実際コンピュータ科学者と呼ばれる人たちの系譜の源流は数学にある。 この時期はおそらくプログラミングが自分にとって一番楽しかった。 なぜなら、普段なら数学の理論なんて作れっこない自分が、コードを書きながら、どういう抽象クラスを作って、どういうインターフェースを作って、その上でどういうクラスを実装するか、といったことを考えながら、1つの数学理論を作るような感覚でプログラミングが出来たからだ。

そして、実際そんなことを考えながら作ったフレームワーク第1号が、ロボットをモデル化してみようと試みたpisatだった。 所属サークルの自立型ロボットの制御プログラムから始まった取り組みだったが、せっかくだからライブラリにしておこう、あれフレームワークっぽくなってきたぞ、ロボットを特徴づける要素は何だろうか、とどんどん脱線しながら、大学の講義そっちのけで作っていたのが懐かしい。 その後、フレームワーク第2号で誕生したのが、bambooだった。 これもバックエンド未経験ながら、バイト先からサーバーサイドやってほしいと無茶ぶりをされて、色々勉強したことをまとめておこうと思ったら、いつの間にかフレームワークになっていた、という産物である。 今見ればどちらも粗削りだが、よくもまあこんなものを作るのに大量の時間を投下したなと思う。

こういった経緯をたどると、自分は OOP が好きだったわけではないことに気付く(Python でフレームワークを書いていたときは、肝心のインターフェースは使っていないし)。 どちらかというと、ある具体的な事象を眺めて、そこから設定を抽象化させて、その中でこれまで見えなかった視点や繋がりを見つけることが好きだったのだと思う。 結局のところ、OOP は単なる入口に過ぎなかった。

OOP に出会う前は、私にとってプログラミングは写生のようなものだった。 そこにゴールは見えていて、ただそれを忠実に再現することが出来るコードは何かが重要だった。 しかし、OOP に出会った後は、プログラミングはキャンバスに自分の頭の中のイメージを描くようなものになった。 そこにあったのは、お花畑が広がった頭の中の世界を、こんなにも自由に表現できるんだという開放感だった。 そして、その体験が私の研究人生の第一歩になったといっても過言ではない。 研究生活の中で何でもかんでも自分で作ろうとするのは、こういう体験があったからだと思う。

一方で、OOP が私に与えたネガティブな影響は、アプリケーションの開発に全く意欲が湧かなくなったことだ。 アプリケーションは仕方なく作るもので、出来ればフレームワークやライブラリを作っていたいと思うようになってしまった。 そして、頭の中で世界が広がらないコードは、どうも読みづらくなってしまった(のか元々そうなのかはわからない)。 もう少し色んなコードに目を慣らせておくべきだったなとも思うが、まあそれはそれで仕方ない。 残念ながら web アプリの実装がまだ残っているので、このへんで現実逃避は終わりにしておこう。


  1. ちなみにもう Java は書こうとしても手が動かない。 ↩

  2. もちろん、本当に数学理論を作っているということは口が裂けても言えないが、ありがたくその擬似体験をさせていただいているという意味である。 ↩

  3. これは数学的に厳密な話ではなく感覚的な話で、実際には実数は線形空間の一種であり、今となっては加法群や可換群といった、より根源的な概念の方がインターフェースに近いと思うが、当時の自分はそういう理解でも十分に知的好奇心が刺激された。 ↩