Smalltalk-72で遊ぶOOPの原点:「sqrt」を実装する(準備編)

アラン・ケイの“メッセージングによるプログラミング”という着想に基づき(非同期処理などいろいろ足りていないながらも──)比較的忠実に実装された1970年代の非常に古いSmalltalk-72に実際に触れてみるシリーズ 第2弾です(なお最新のSmalltalkについては Pharo などでお楽しみください!)。

今回は謎言語「Smalltalk-71」で書かれたスペースウォー・ゲームSmalltalk-72に移植して動かすことを目指します。前回(2019年)を含む他の記事はこちらから→Smalltalk-72で遊ぶOOPの原点 | Advent Calendar 2023 - Qiita


まず abs を実装する

sqrt は、Smalltalk-71 の Spacewar ではここまで出てきた sqrt 3 としか使っていないので、1.73 を返す今の仮実装のままでも問題ないわけですが、何かのおりに使うかもしれませんので、この機会に書いておきます^^;

その前に、Smalltalk-72 には abs も無いのでこれをアクションとして用意します。Smalltalk-80 では abs は Number などのメソッドして用意されていますが、数値もメッセージとして送ることができ、かつ、継承の無い Smalltalk-72 では、アクション abs への数値の送信というスタイル(abs x)の方がなんとなくシンプルで良さそうです。

to abs x y (0 > :x ? (!-x) !x)

もちろん number など必要なクラス全てにメッセージ abs へ応答するためのメソッドを追加することで Smalltalk-80 以降のスタイル(x abs)にもできます。

既存のクラスへメソッドを追加するには addto アクションを使います。

addto number "(%abs ? (0 > SELF ? (!-SELF) !SELF))
addto float "(%abs ? (0.0 > SELF ? (!-SELF) !SELF))

ちなみに、Smalltalk-72 は - x はアクション - への x の送信です。ALLDEFS で to - を探すか、エミュレーター側で show - を評価することでその定義を見ることができます。なお、Smalltalk-72 で負数リテラル- ではなくオーバーバー̄(入力時はバッククオート)を使います。

繰り返しになりますが to - x ...xSmalltalk-71 のプロシージャの仮引数に似ていてもそれとは別で、たんなるテンポラリ変数宣言です。メッセージとして送られてきた数値は続いて括弧でくくられて記述されるメソッド本体冒頭の :x のところでフェッチ&アサインされます。

これもしつこいですが、:x もアクション: へのシンボル x の送信です。Smalltalk-72 はほぼすべてがメッセージングで記述されます。唯一の例外が条件分岐(式⇒(非偽時処理) 偽時処理)というのも、Smalltalk-80 と違っていて面白いですね。(いろいろ最適化している Smalltalk-80 ではメッセージでやっていないことは Smalltalk-72 より多いのですが、条件分岐は ifTrue: [] ifFalse: [] というメッセージを送信する、少なくとも“フリ”はしています。)

『sqrt』を実装する(コードと解説編)へ続く)