NetBeansとScalaで遊ぶ(遅延評価編)

忙しくてしばらく使っていなかったScalaNetbeans、新しいバージョンを入れてみる。
Netbeansが6.8、Scalaは2.8.0.RC2、Scalaプラグインがnb-scala-6.8v1.1.0rc2b。
ScalaIDEサポートは、もう十分使えますね。(Eclipseプラグインは知らんけど)

そして、すっかり忘れてしまったScalaの復習。
ブレークポイントからステップ実行して挙動の確認。(←こういう発想は関数型が身についていない証拠?)
Scalaの対話式実行環境よりこちらのほうがやりやすい。

遅延評価の確認で以下のコードをステップ実行

var foo = "foo"      // (a)
lazy val bar = foo   // (b)
lazy val baz = foo   // (c)
foo = "bar"          // (d)
println(bar)         // (e) => "bar"が表示される
foo = "baz"          // (f)
println(baz)         // (g) => "baz"が表示される

最初の行のブレークポイントで停止(a)。
この時点で変数ウィンドウにfoo,bar,bazは登場しないが、謎のbitmap$0$1というIntRef型の変数が。
この時点でIntRefが参照しているintの値は0。
次行にステップオーバー。(b)
変数ウィンドウにfooが登場するかと思ったらfoo$1というObjectRef型の変数登場。
foo$1が参照しているのは文字列"foo"。
遅延評価される変数が束縛された変数は特別扱いらしい。
次行にステップオーバー。(c)
barは変数ウィンドウに登場しない。これは登場したらその時点で評価されてしまうので当然。
代わりにbar$lzy$1というObjectRef型の変数登場。参照先はnull。
(d)(e)とステップ実行して次に(f)に行くと思ったら(b)に戻ってしまった。
この行が評価されたよ、という意味なのか。そして再び(e)に戻る。
この時点でbar$lzy$1の参照先は文字列"bar"になっていた。
そして、bitmap$0$1の参照先のintの値が1に。
(g)を実行し終わった時には、bitmap$0$1の参照先のintの値は3になっていた。

bitmap$0$1は、各ビットを遅延評価変数が評価されたかのフラグとして使っているらしい。
では、64を超えた数の遅延評価変数と定義したらどうなるか・・。bitmap$1$1という変数が登場しました。

おまけ
上記の(a)の行と(b)の行を入れ替えてもNetBeans上でエラーになりません。
束縛元の定義が後でもいいという超遅延評価?
当然、コンパイルするとエラーになります。