「Scratch全然わからない」問題

子供がたまにScratchをやっている。日本では日本語でプログラミングを勉強できてそこそこメジャーな環境がほぼScratchしかないのでどうしても小学生のプログラミング学習はScratchになりがちだが僕はScratchがどう役に立つのかよくわからず子供に積極的に勧める気にはなれないのである。

 

 

それはそうとしてScratchを触ってみるといろいろわからないことが多いことに気づく。たとえば下記のようなプログラムを作ったときの実行順序はどうなるのだろうか。

f:id:naoya2k:20191006000441p:plain

どういう順序で実行されるのか

試してみたところ、結果は下記のようになった。

f:id:naoya2k:20191006000940p:plain

結果

まず左側のコードが実行され、ループの1回目が実行された時点で(XLに1が追加された後)、右側のコードが実行が開始される。右側のループの1回目が実行されたタイミングで(XLに101が追加された後)、左側の2回目のループに戻り、次に右側の2回目のループを実行する。その後同様にループを交互に実行する感じで実行が進む。つまりこのイベントハンドラのルーチンはそれぞれがコルーチンあるいはスレッドとなっていて。ループがあると1回ごとにYieldが発生して次のスレッドに制御が移る。

猫を動かすサンプルコードで「10歩動かす」を「20回繰り返す」で囲んで動かしたときにずるずる画面上で動くことが確認できるので、「繰り返す」ループの1ループ分が一回の画面更新の間に行われる処理となっているものと思われる。

 

しかしこれは環境によって変わることがないのだろうか。猫を繰り返し動かすようなサンプルではなく上の例のような、UIに対する副作用の無いコードがループでYieldされるのはむしろ不自然なのではないだろうか。

ちなみにYieldされたくない場合は、Scratchにおけるサブルーチンであるところの「ブロック定義」の中にループを置き、そのブロック定義の編集画面で「画面を再描画せずに実行する」のチェックを入れれば1ループ毎にYieldされることはなくなる。

 

また、たまたま今回は左側のコードが先に実行されたが、これはおそらく左側のコードブロックを先に書いたからである(これをドラッグして画面上での左右の位置を入れ替えても動きは変わらなかった)。どちらが先に実行されるかどうかが見た目でわからない。これをちゃんとするためには「メッセージを送る」という機構がScratchには用意されていてそれを使うと良い。

f:id:naoya2k:20191006093055p:plain

メッセージを使った例

しかしスレッド内のループの実行順序についてはいまの挙動通りに動いてくれると考えてはいけないような気がしているが、その実行順序をこのメッセージでなんとかするのは困難だと思う。ここまで書いてきたような部分は今回調べてなんとなくわかった感じもするが、それ以外にも挙動がよくわからないことが複数あって、全然わからないという印象につながっている。

 

Googleでいろいろ調べていたら、複数スクリプトの同期について教えることに関するPaperを発見した。

8216-28003-1-PB.pdf

これによれば、小学校5年生にConcurrent programmingでのSynchronization issues (race conditions)を教えることにチャレンジしており、それなりの率の生徒がその目標に達成しているとのことなのですごいと思った。