ScratchがSmalltalkで実装されていると何ができるのか？

序
===

去る2017年12月2日のNGK2017B(名古屋合同懇親会 2017年 忘年会)でSmalltalkからScratchをいじるデモをしました。この記事では、何をやっていたのかの解説をします。
<a href="https://www.youtube.com/watch?v=sqZE8Ztat_A#t=6m32s">
<img width="512" src="https://qiita-image-store.s3.amazonaws.com/0/12251/0ae86ee1-5e49-cb12-415d-bad600fab9ae.png">
</a>

なお、8分30秒あたりで近くにいた こはま([c0hama](https://twitter.com/c0hama)) さんを唐突に呼んで、前で操作してもらいました。
「あー」とか「えー」とか言っているのは、こはまさんです。協力ありがとうざいました。

説明
===
### Smalltalkを出す (6分36秒あたり)
<img width="512" alt="スクリーンショット 2017-12-05 20.48.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/12251/4b601958-22ff-d17d-340c-c567ccc90c3a.png">
  左上のScratchのロゴのRの穴のあたりをShiftを押しながらクリックするとメニューが出て来ます。"turn full screen off"をクリックすると、通常隠されているSmalltalkが現れます。
最新のScratchはFlashで実装されていますが、Scratchは当初Smalltalkで実装されていました。プロダクトとして出す場合は開発用のツールは消すことも可能ですが、Scratchは教育用ということもあり、開発環境も揃ったままの状態でリリースされています。

### 差分のコードを取り込む (6分47秒あたり)
<img width="512" alt="スクリーンショット 2017-12-05 20.49.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/12251/89e6c990-e079-ab20-35c9-1d77d2bf5036.png">
  Smalltalkの環境はコードのバージョン管理の機能も同梱されています。メソッド単位でコードの変更が記録されており、差分をファイルに出力したり、差分を取り込んだりすることが可能です。他の言語でも言語要素を単位にしたバージョン管理ができるといいですね。
　ウィンドウのデザインにレガシーな雰囲気が漂いますが、Scratchを動かしているSmalltalkがかなり古いためです（20年以上前のもの？）。逆にこんなに昔から様々な先進的な機能を取り入れていたことに驚きます。

### 部品を選択する (6分56秒あたり)
<img width="512" alt="スクリーンショット 2017-12-05 20.49.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/12251/9193dd11-7645-1226-3890-9fc3e3a9fd5d.png">
  Scratchの見た目に関する部分はMorphicという仕組みで実装されており、目に見える様々なものがMorphというクラスを継承して作られています。Morphを右クリックするとMorphのまわりに丸いものが表示されます。これをHaloと言います。Haloを使って、Morphのサイズ変更・複製・削除をしたり実装クラスのコードを見たりできます。
Morphは子Morphを複数持つ階層構造になっています。右クリックを何度もすると子Morphに潜っていくことができます。
ここではステージ上部のパネルのHaloから、オブジェクトの内部状態を見るウィンドウを開いています。このウィンドウをインスペクタと言います。インスペクタからオブジェクトに対してメッセージを送って対話的にプログラムすることができます。

### スプライトやブロックをプログラムから作る (7分8秒あたり)
<img width="512" alt="スクリーンショット 2017-12-05 20.49.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/12251/934d110a-ef35-0b22-b3ed-acb37f32af97.png">
  Scratchの音を鳴らすブロックをつなげて実行すると、一つの音が鳴り終わるまで待ってから次の音が鳴ります。複数の音や動きのタイミングを合わせるために、それぞれの音の高さ/長さに対応するメッセージを送り、それを受け取ってその音を鳴らすブロックを用意しています。大量のブロックが必要ですが、プログラムを作れば単純な反復作業もすぐ終わります。

### ボタンをつける (7分18秒あたり)
<img width="512" alt="スクリーンショット 2017-12-05 20.50.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/12251/cb8292ee-40b1-d030-168e-9378d4f25f80.png">
  アプリケーション実行中でも、自由にカスタマイズすることができます。

### スプライトを画面の外に取り出す。(8分04秒あたり)
<img width="512" alt="スクリーンショット 2017-12-05 20.51.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/12251/8c07e6cc-fda5-fc4f-a8ab-297b3f72a4be.png">
  スプライトもMorphで実装されています。内部的には画面の外に出す操作は、スプライトのMorphの親Morphが変更(ステージのMorph→背景のMorph)されただけのことです。

### Scratch を爆発させる(8分15秒あたり)
<img width="512" alt="スクリーンショット 2017-12-06 1.01.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/12251/9036b2a4-a22f-60c3-b9f2-02078773f37d.png">
Scratchを構成する部品も自由に操作できます。

### バグを踏む (9分01秒あたり)
<img width="512" alt="スクリーンショット 2017-12-05 20.51.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/12251/b3086c7d-bd5b-ab8c-7d2e-6427a69aae30.png">
  例外が発生すると実行スレッドが停止し、どうするか尋ねるウィンドウが表示されます。Debugボタンを押すと、該当箇所のコードが表示されます。

### バグを直す (9分19秒あたり)
<img width="512" alt="スクリーンショット 2017-12-05 20.52.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/12251/c32f63c4-9d49-5eee-5dbe-3066ec28d792.png">
  赤いウィンドウには例外発生時のスタックトレース、コード、変数などが表示されています。さらに内部を調べるために変数を選択してインスペクタを開くことが可能です。インスペクタからインスタンス変数lifeが設定されていないことを確認しました。インスペクタの下の枠からSmalltalkのコードを実行して、オブジェクトに対してメッセージを送ることができます。ライフのオブジェクトをインスタンス変数に代入した後にスレッドをメソッドの先頭から再実行しました。

### ウィンドウが襲ってくる (9分34秒あたり)
<img width="512" alt="スクリーンショット 2017-12-05 21.16.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/12251/f73ec772-e664-cf17-4404-1ff68559bc55.png">

  オレンジのウィンドウはTranscriptというログを表示するためのウィンドウです。緑のウィンドウはシステムブラウザといってコードの編集などを行います。このようなシステムが提供しているウィンドウもMorphで実装されており、アプリケーションと同じ世界のオブジェクトして存在しています。そのため、スプライトなどと同じように動かしたり、当たり判定をすることができます。デモではやっていませんが、システムウィンドウのハロを表示して内部状態をのぞいたり、実装コードを開いてコードを変更してシステムの基本的な部分も好きにカスタマイズしたりすることもできます。Smalltalkの文法を変えて別の言語にすることだってできます。

### ブレイクポイントで止める (9分56秒あたり)
<img width="512" alt="スクリーンショット 2017-12-05 20.52.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/12251/d078737d-2ef1-76d8-8511-a872fbcebe9c.png">
  Smalltalkでブレイクポイントを仕込みたいときは、`self halt`というコードを入れておき、そこを通ったときに例外を発生させて止めます。停止後に起動したデバッガから`self halt`を削除するようコードを編集して、再実行すればもう止まりません。デモ中、数秒の待ちが発生してますが、これは後続の処理で行われる拡大や回転などの負荷が高い計算を事前にメモリに乗せるコードをコメントに仕込んでおいたので、それをデバッガ内で実行しているためです。

### ネコが増殖する (10分12秒あたり)
<img width="512" alt="スクリーンショット 2017-12-05 21.35.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/12251/b3b6ca0f-8038-d7d7-deb4-f14139d741d4.png">
  ネコの増殖の仕方を決めるメソッドを書き換えるコードを実行して動きをコントロールしています。該当コードを表示してコードがパカパカ切り替わる様子を見せてもよかったなぁと反省しています。

結び
===
Smalltalkの環境では実行中になんでも自由にいじれます。日頃お使いのアプリケーションがSmalltalkのように制限なく自由に中身を覗けたり、自分好みに変更できたら、と想像してみてください。Smalltalkは個々人の能動的な創造性を発揮するための環境を目指して開発されました。Smalltalkがどのような思想のもとに作られたかは、アラン・ケイが1972年（40年以上前！）に発表した[あらゆる年齢の子供たちのためのパーソナルコンピュータ](http://swikis.ddo.jp/abee/74)という小論文で知ることができます。

あと、なごやのコミュニティはやさしいので、だいたい何をやってもあたたかく迎えてくれます。好き勝手やりましょう。