なんせ少なくとも四半世紀前の記憶を元に記事を書くものだから説明の誤りや不足があればコメントまたは編集リクエストが欲しいです。
#定義
##GOTO
とは
BASICにおけるGOTO
とは指定の行またはラベルへと実行行を飛ばす命令である。
10 PRINT "Hello, world!"
20 GOTO 10
RUN
BASICのインタプリタは行の先頭の数値を認識し、原則としてその数が少ない行から順に実行する。
GOTO
を用いると、例外的に実行行の順序を変更することができて便利であった。
上記の例は"10"と書かれた行の命令を実行し続ける無限ループである。
##ラベルとは
BASICには自動で行を割り振ってくれるIDEのようなものがあったが、ソースコードが肥大化するにつれ行番号での実行制御では可読性が下がるのは避けられない。そこで便利なのがラベルという概念であった。
10 *START
20 PRINT "Hello, world!"
30 GOTO *START
RUN
上記は先ほどの例と同じ処理をラベルを用いて書き直したものである。
#良くないGOTO
の使い方
現在においては、おおよそほとんどのGOTO
命令が非推奨である。理由としては下記の通り。
- ラベルを用いてもなお可読性が低い
- 制御構造がわかりづらい
- ネストが難しい
##ラベルを用いてもなお可読性が低い
GOTO
命令による実行行の移動が一方向であるため、ソースの読者は行き先のラベルを探して読まなければならず、行き先で再度GOTO
命令が書かれていた場合、その都度行き先を探さなければ読めなかった。
10 *START
20 GOTO *INIT
30 *MAIN
40 PRINT X
50 GOTO *MAIN
60 *INIT
70 LET X = "Hello, world!"
80 GOTO *MAIN
RUN
現代的なスクリプトではこのように書きがちだが、これは以下の文と等価である
10 LET X = "Hello, world!"
20 PRINT X
30 GOTO 20
RUN
##制御構造がわかりづらい
単なる実行行の移動なのか、またはループを作るためにGOTO
したのかが読まなければわからない。
これは大きなプロジェクトでは致命的であった。
##ネストが難しい
多重ループ制御をGOTO
で実装することは可能ではあったが、ラベルを用いてもエンバグの恐れがあり、また可読性は著しく下がるものだった。
#代案
そこで便利だったのがGOSUB
命令である。RETURN
命令とセットで用いることにより実行行を飛ばした後でも元の位置に戻って来ることが保証されていた。
##GOSUB
とは
「最後に実行したGOSUB
命令の直後」まで自動的に戻ってくる命令である。見た方が早い。
10 *START
20 GOSUB *INIT
30 *MAIN
40 PRINT X
50 END
60 *INIT
70 LET X = "Hello, world!"
80 RETURN
RUN
###GOSUB
命令の注意点
- 引数を指定して
GOSUB
することはできない。 - __
RETURN
命令が返り値を取らない__ことにも注意。
BASICでのRETURN
はあくまでも「最後に実行したGOSUB
命令の直後に戻る」命令であり、関数型のサブルーチンを定義するためのものではなかった。
なお、BASICの変数は全て、今で言うところのグローバルなので、宣言や定義に悩むことはなかった。
#本記事について
某キャンペーンとの関係はございません。