Smalltalk-72で学ぶOOPの原点:条件分岐以外の制御構造
アラン・ケイの“オブジェクト指向”というアイデアをもとに(非同期処理などいろいろ足りていないながらも──)比較的忠実に実装された1970年代の非常に古いSmalltalk-72で遊んでみるシリーズです(なお最新のSmalltalkについては Pharo などでお楽しみください!)。他の記事はこちらから→Smalltalk-72で学ぶOOPの原点 Advent Calendar 2019 - Qiita
(条件分岐式についてもう少しからの続き)
Smalltalk-72のforループ
いわゆるforループは for <変数名> ← <開始値> to <終了値> by <差分> do (<処理>)
のように書きますが、条件分岐が 'if' アクション(オブジェクト)へのメッセージ送信で実現されているのと同様に、もちろん for
アクションへのそれで実現されています。
例によって完全な仕様は ALLDEFS(ブートストラップコード)で for
アクションの定義を読むのが手っ取り早いです。
for
アクションの定義(to for …
)token
step
stop
var
start
exp
という一時変数の宣言- まず、メッセージの最初のトークンを評価せずにそのまま
var
に取り込む(:☞var.
) - 続くメッセージで
←
がマッチしたら、メッセージの続きを式として評価してstart
に取り込む(∢← ⇒ (:start.)
) - そうでなければ、
start
の値は 1 に(☞start ← 1
) - 続くメッセージで
to
がマッチしたら、メッセージの続きを式として評価してstop
に取り込む(∢to ⇒ (:stop.)
) - そうでなければ、
stop
の値はstart
と同じ値に(☞stop ← start.
) - 続くメッセージで
by
がマッチしたら、メッセージの続きを式として評価してstep
に取り込む(∢by ⇒ (:step.)
) - そうでなければ、
step
の値は 1 に(☞step ← 1.
) - 続くメッセージで
do
がマッチしたら、その参照をexp
に取り込みプリミティブCODE 24
をコール(∢do ⇒ (:#exp. CODE 24)
)
差分はもちろん、初期値も終了値すらも省略可能である仕組みがよく分かって面白いですね。なお、プリミティブ CODE 24
は、一時変数を取り込んで実質的なforループ処理を実行します。コメントにもあるように後述のdone
(中断して抜ける)やagain
(中断して次の回の処理を実行)も使えます。
その他のループ
forループの他にも、単純なループのrepeat
(停止するときは esc
キーを押す)や
今のSmalltalkのtimesRepeat:
、Rubyのtimes
にあたるdo
もあります。ただし、今のSmalltalkやRubyが整数にメッセージを送る(体になっている──)のに対し、Smalltalk-72ではdo
自身がループ回数を表す整数を含めたメッセージの受け手になっていて、結果、記述順が異なるので要注意です。
done
とagain
done
はループを中断して抜けるアクションです。with <値>
で、ループを抜けたときの返値を指定することもできます。
again
はRubyでいうところの(redo
ではなく)next
の役割を持つアクションのようです。
(文字列操作…の前にクラス定義についてに続く)