Smalltalk-72で遊ぶOOPの原点:Smalltalk-71について
アラン・ケイの“メッセージングによるプログラミング”という着想に基づき(非同期処理などいろいろ足りていないながらも──)比較的忠実に実装された1970年代の非常に古いSmalltalk-72に実際に触れてみるシリーズ 第2弾です(なお最新のSmalltalkについては Pharo などでお楽しみください!)。
今回は謎言語「Smalltalk-71」で書かれたスペースウォー・ゲームを Smalltalk-72に移植して動かすことを目指します。前回(2019年)を含む他の記事はこちらから→Smalltalk-72で遊ぶOOPの原点 | Advent Calendar 2023 - Qiita
謎言語「Smalltalk-71」
実際に動作する Smalltalk処理系は 1972年の9月ごろに BASICで書かれた、のちに「Smalltalk-72」と呼ばれることになる言語の初期のバージョンが最初ですが、それ以前にも「Smalltalk-71」という、同じくアラン・ケイ氏考案の、これまたまったく別の言語がありました。かなり具体的な仕様まで考えられていたようで、たとえば構想段階の「ダイナブック」を紹介した「A Persona Computer for Children of All Ages(あらゆる年齢の『子供たち』のための パーソナルコンピュータ)」にも、今回扱うローリングストーン誌同様にコードを例として入れようとしていたようです。(このときは結局、ダニエル・G ・ボブロー氏の助言により取り除かれました。)
はずかしながらこのSmalltalk-71という言語については、カール・ヒューイットのPlannerという言語などからの影響で、文法を自由に定義できる機能を持っていたり、また、アラン・ケイ自身が1966年頃にアイヴァン・サザーランドのSketchpadやダールらのSimulaⅠ(この時点ではまだクラスやオブジェクトという用語は使われていなかった)のソースコードを読んでいてひらめいたオブジェクトやメッセージングの概念を(少なくともコンテキストレベルでは)持っていた…という程度の知識は「The Early History of Smalltalk(Smalltalkの初期の歴史)」から得てはいたものの、正直、ちんぷんかんぷんな状態でした^^;
「Smalltalkの初期の歴史」に掲載された Smalltalk-71 で、and演算、factorialやis-member-ofといった関数、Lisp の CONSセルのようなデータ構造、そして、ロボットの動作(!?)を実装した例がこちらになります。
一方で、呼び出し時のコンテキスト(スタックフレーム)はこんな構造を想定していたようです。
フィールド名 | 説明 |
---|---|
グローバル (GLOBAL) | パラメータ値の環境 |
送信者 (SENDER) | メッセージの送信者 |
受信者 (RECEIVER) | メッセージの受信者 |
返信スタイル (REPLY-STYLE) | 返信の方法(例:待機、分岐等) |
状態 (STATUS) | メッセージの進行状況 |
返信 (REPLY) | 最終的な結果(存在する場合) |
操作セレクタ (OPERATION SELECTOR) | 受信者に関連した操作 |
パラメータ数 (# OF PARAMETERS) | パラメータの数 |
P1, ..., Pn | 各パラメータ |
メッセージやセレクタといった、のちの Smalltalk でよく見かける用語も登場するものの、実際にそれらが、たとえば前述のようなコード上のどんな記述にどのように対応するのかははっきりと理解できないままなおざりにしてしまっていました。
では改めて、今回の Spacewar のコードの全体を眺めてみましょう。
まず、前述「Smalltalkの初期の歴史」版とは明らかに違う別の文法が用いられていることがわかります。「初期の歴史」版のようなにみられる is self のような明示的な記述は見当たりません。しかし、一部に :self という変数名が使われていることから、クラス定義を意識した部分もありつつ、たんなる関数の定義のセクションもある、そんな感じにも見て取れます。
この謎仕様の言語とそれで書かれたコード、なかなか手ごわそうです^^;
(宇宙船を描く(失敗編)へ続く)