普通の bind と lazy bind

昨日、JGGUGG* ワークショップに参加しました。

Groovy のことはあまり知らないので、内容は他の人に譲るとして...

なんと、SwingBuilder や GroovyFX で bind が使えるらしいのです。でも、そのバインドが普通の bind なのか lazy bind なのか分からない。で、質問したのですが、lazy bind が通じなかった orz

一応説明したのですが、口頭だったのでたぶん通じなかったと思います。

ということで、あらためてここで普通と lazy の違いを説明しておきます。

Groovy で書くと時間がかかってしまうので、さくっと JavaFX Script で書きます。

たとえば、次のようなコードがあったとします。

var x = 0;
var y = bind x;

x = 1;
x = 2;
x = 3;

println(y);

x と y が bind されているので、実行したら 3 が出力されます。

この時、各ステップで y がどのように変化しているかを考えます。普通の bind の時は次のようになります。

var x = 0;
var y = bind x;  // y を 0 に更新

x = 1;           // y を 1 に更新
x = 2;           // y を 2 に更新
x = 3;           // y を 3 に更新

println(y);      // y を評価

つまり、普通の bind では y が評価 (使用) されたどうかは関係なく、x が更新されたらその都度 y が更新されます。

ここでは int 同士の単純な bind なのでいいのですが、大きいオブジェクトで bind したりすると、それなりの処理が必要になってしまいます。

これに対し、lazy bind は y が評価される時に、y の値を更新します。

var x = 0;
var y = bind x;  // y を 0 に更新

x = 1;           // y の変更はなし
x = 2;           // y の変更はなし
x = 3;           // y の変更はなし

println(y);      // y を評価するので、y を 3 に更新

つまり、lazy bind は y が評価される時になってはじめて値を更新するのです。値の更新を評価時まで遅延させるので lazy というわけです。

JavaFX ではインタープリターバージョンやαの時は bind と lazy bind を明示的に記述する必要があったのですが、JavaFX 1.0 からはデフォルトで lazy bind になっていまっす。JavaFX 2.0 の bind も lazy になっています。

で、SwingBuilder の bind はどっちなんだろう? GroovyFX の bind は JavaFX の bind だと思うので、lazy だと思うけど...