言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

Skeleton

明日のSmalltalk 勉強会のプレゼンのために未踏で作った Skeleton を引っ張りだして久しぶりに遊んでみたのですが、さっぱりわけが分からなかったので二度と忘れないように記録に残します。Skeleton とは、Squeak のために作った制約システムです。見た目はただのスプレッドシートですが、Excel のような普通のスプレッドシートと違って Morphic と組み合わせる事で面白いアニメーションを簡単に作れるようになっています。

操作方法

デモ用の Squeak イメージは http://languagegame.org:8080/propella/uploads/57/Skeleton-2004-01-25.2.zip にあります。操作方法はだいたい http://languagegame.org:8080/propella/62 を読めば分かると思います。

まず最初は Skeleton のシートを Supplies ビンから引っ張りだして使います。シート全体の移動やサイズ、名前の変更はハロを使います。

option + クリックでコンテキストメニューが表示されます。

  • formula: 式表示モードと値表示モードを切り替えます。
  • reveal this project: モーフの参照がセルに入っていれば選択する。
  • library: library シートを表示します。
  • copy: 選択したセルをコピーします。
  • cut: 選択したセルをカットします。
  • paste: 選択したセルをペーストします。
  • spawn: 選択したセルを Smalltalk ワークスペース形式で表示します。

シートの左上の時計ボタンは、Connector を使ったデモに使います。三角ボタンは後述の名前空間を移動するのに使います。

Skeleton の設計

Skeleton の設計で Excel と根本的に違う点が三つあります。

  • Excel のセルには数や文字列など具体的なデータが入ってますが、Skeleton のセルは参照です。
  • Excel ではセルに値か式のどちらか一方を入れるが、Skeleton では両方を入れます。
  • Skeleton ではシートの中にシートを埋め込ます。親のシートは子のシートの式を使って値を計算します。つまり、ライブラリとして他のシートを使う事が出来ます。

それぞれ説明して行きます。

Skeleton ではセルに参照を入れる

普通の使い方では、Skeleton のセルも Excel のマスも同じようにデータを入力する事が出来ます。例えばセルを選択して、123 と打つと数字が入り、=A1+A2 と打つと式が入ります。少し違うのは、Skeleton のセルには他のオブジェクトの属性を関連付ける事が出来る点です。例えば EToys で車の絵を書いて向きや位置のタイルを Skeleton のセルにドラッグすると、セルは常にその絵の向きや位置を追跡します。

内部的にはセルに三つの属性があって、それぞれオブジェクト本体、表示用メソッド、更新用メソッドが保存されています。普通の値をセルに入れる時は ValueHolder というダミーのオブジェクトへの参照になります。

Skeleton では値と式の両方を入れる

Excel では、一つのセルに値か式のどちらかを入れます。しかし Skeleton ではセルに式が入っている時、このセルに後から参照を入れる事が出来ます。例えばセルに車の絵の座標が入っている時、同じセルに式を書き込むと車の座標を Skeleton から制御する事が出来ます。

内部的には、値と式の両方を一つのセルに持つ事でこの機能を実現しています。また、値と式を両方持つことで、双方向参照のある式を書く事が出来ます。もしも双方向参照が出来ても Skeleton は適当に検出して無限ループが起こらないようにしてくれます。

Skeleton では、他のシートを埋め込んでライブラリとして使う事が出来る

シートに何度も同じ式を入力する事がよくあります。そういう時、Skeleton では良く使う式を保存して使いまわす事が出来ます。

この時に使うのがカードという仕組みです。カードを作るには、新しいシートの一番上の行に使いたい式を書き、ハロで名前を変更した後黄ハロでぐぐっと小さく縮めます。するとつけた名前のカードが出来ます。タイルの左の取ってを掴むと移動出来るので、そのまま別のシートに貼り付けると、カードに定義してある数式を使う事が出来ます。カード名の取っ手の無い部分をダブルクリックすると、再びカードの内容を編集出来ます。カードとシートは見た目が違うだけで同じ物です。

名前空間

Skeleton では、「名前は名乗るものではない、名指しされるものだ」というポリシーを貫いています。と言う事で、黄ハロで変更した名前はシート自身が持っているのではなく、そのシートが属するプロジェクトシートという物が持っています。プロジェクトシートの名前もプロジェクトシートが属する Projects が持っていて、さらに Projects は Root によって定義されています。シートにはこのように名前を定義するツリー構造で出来ています。

Root には Projects の他 Library という特別なシートがあって、そこにどのシートからでも参照出来るグローバルなカードを登録します。

Skeleton の欠点

Skeleton の最大の特徴は、内部的にセルに値と式の両方を入れることで双方向参照を可能にした所です。しかし UI 的に両方入っているというのはなかなか直感的では無いようで、操作を間違えやすいしバグの温床になっていました。と言う事でこちをもうちょっと気をつけて実装すれば良かったかなと思っています。2004 年に未踏で発表した後、自信を無くして開発は終わってしまいました。それから他の制約システムや関数型言語を学びましたが、今になって触ってみるとバグだらけの実装はともかく自信を無くすほどひどいアイデアでは無かったなと思っています。逆に Skeleton で解決出来ると思っていた様々な問題を思い出し当時の野望の高さに驚いています。

デモの説明

http://languagegame.org:8080/propella/uploads/57/Skeleton-2004-01-25.2.zip の簡単な説明

  • Title: ガイコツを押すと開始。ガイコツを回すと星も動く。
  • Basic Function: シートの左下のボタンを押して次に進んでゆきます。
  • Connectors: カードのコンテキストメニューでコネクタを出して丸にくっつけて遊びます。
  • Triangle and rule: コネクタによりハロでコネクタの長さを変えても三角形を維持します。コネクタのビューワから長さのタイルをシートにドラッグし、関連付けを行います。例えば二等辺三角形を作る事が出来ます。
  • Midpoint: 三角形の重心を求めます。
  • Spring: バネを使った例です。
  • Lissajous: 星を動かすとリサージュ図形が現れます。
  • Composite function: なんか忘れましたが綺麗な図形が出ます。
  • Simple Solver: ソルバの解説です。どのロケットを動かしても他のロケットが動きます。