Smalltalk-72で学ぶOOPの原点:継承が…ない!(「is?」の実装)

アラン・ケイの“オブジェクト指向”というアイデアをもとに(非同期処理などいろいろ足りていないながらも──)比較的忠実に実装された1970年代の非常に古いSmalltalk-72で遊んでみるシリーズです(なお最新のSmalltalkについては Pharo などでお楽しみください!)。他の記事はこちらから→Smalltalk-72で学ぶOOPの原点 Advent Calendar 2019 - Qiita


継承が…ない!(クラス変数の活用)からの続き)

クラスを問い合わせるis?

継承がないということは、Objectに代表される“すべてのオブジェクトの振る舞いを決める基底クラス”もないわけで、つまり、クラスを問い合わせるメッセージis?のような基本操作にも、そのパターンマッチをいちいち定義しておかなければ応答がままならないことを意味します。

f:id:sumim:20191210104251p:plain
タートル「😄」、文字列「'abc'」、配列「☞(1 2 3)」は「is?」に応答できるが…

f:id:sumim:20191210120113p:plain
それは、これらのクラスで「is」のパターンマッチが明示されているから

多くのクラス(のインスタンス)がis?に応答できるのは、単純にisのパターンマッチが定義されているからなのですね。

ISITの正体

ではここでeval(評価)されているISITとは何者でしょうか? 定義はこんな感じです。

f:id:sumim:20191210121413p:plain
「ISIT」の定義

続くトークンが?(タイプして入力するときは~)なら、クラス名(TITLEプロパティ)を返し、そうでなければTITLEプロパティと続くトークン(評価せずに取り込む:☞)と等価ならそのまま、等価でなければfalseを返す…というコード片と同義の配列が、グローバル変数ISITに代入されたものとなっています。

運用時はこれにevalを送ることで評価できます。シェアしたいコード片(処理)を配列のままグローバル変数に保持し、各クラスでの記述を最小限にするという継承の無い辛みを軽減するもうひとつの工夫ですね。

f:id:sumim:20191210124028p:plain
「is」と「is?」に対する振る舞い

エラーにならないis?

クラスはisnewアクションを呼ぶアクションに過ぎないことは既に述べましたが、この最少構成であるクラス(仮にfooisのパターンマッチはあえて定義しない)のインスタンスを使ってis?にどんな応答をするか調べてみましょう。

f:id:sumim:20191210122501p:plain
パターンマッチが定義されていないのにエラーにならない「is?」

あれ? おかしいですね。fooとこそ返しませんが、untypedなどとそれっぽい答が返ってきます。これはいったいなぜでしょうか。

知らないメッセージはスルーする?に続く)