衆合智サービスと検閲と言論の自由と
Microsoft oFone!?

JavaFX Script 入門、とりあえず言語仕様に目を通してみた

 CNetでも報道された通り、Sunが独自のスクリプト言語JavaFX Scriptを発表した。テクノロジーの優劣だけで決まるものではないので、この試みがうまく行くかどうかは何とも予測しがたいが、とりあえず言語仕様が公開されたので目を通してみた。

 私なりに興味深いと思った点は以下の5つ(ただし、私なりの拡大解釈が多少入っている可能性もあるので要注意)。

1.宣言型のUIをサポートしていること

 宣言型大好き人間の私としては、この方向性は大賛成(ちなみに、UJMLも宣言型のUI言語^^)。"押してね!"というラベルがついたボタンを表示するには、こう書けば良い。

        Frame {
              content: Button {
                   text: "押してね!"
                   action: operation() {
                        System.out.println("押してくれて、ありがとう");
                   }
              }
              visible: true
         }

2.配列・文字列のオペレーション

 C++やJavaが進歩を止めている間に、スクリプト言語は大幅に進歩してきたが、やはり生産性の向上という意味では、配列と文字列のオペレーションがライブラリーではなくて言語レベルでキチンとサポートされている点がスクリプト言語の一番の強みと私は感じている。もちろんSunもそこははずさずに来た。下のサンプルは、配列に対するinsertやdeleteなどのオペレーション。

        var x = [1,2,3];
        insert 10 into x; // yields [1,2,3,10]
        insert 12 before x[1]; // yields [1,12,2,3,10]
        delete x[. == 12]; // yields [1,2,3,10]
        delete x[. >= 3]; // yields [1,2]
        insert 5 after x[. == 1]; // yields [1,5,2];
        insert 13 as first into x; // yields [13, 1, 5, 2];
        delete x; // yields []

 その中でも便利そうなのが、SQLのように配列に対してqueryをかけて別の配列を作るselect。下のサンプルは、各アルバムの曲の中から、アルバムのタイトルと一致するトラックのインデックスを新たな配列として作っている。

        var titleTracks =
            select indexof track + 1 from album in albums,
                      track in album.tracks
                          where track == album.title;

 このqueryはforeach文にも適用できて、その場合は、

            foreach (album in albums,
                      track in album.tracks
                          where track == album.title)

となる。

 そして文字列のオペレーション。スクリプトを使いこなしている人たちにはあたり前だが、文字列中の変数やステートメントを展開してくれるのはやはり便利だ。

        var name = 'Joe';
        var s = "Hello {name}"; // s = 'Hello Joe'

        var answer = true;
        var s = "The answer is {if answer then "Yes" else "No"}"; // s = 'The answer is Yes'

3.非同期な実行

 興味深いのが、do later ステートメントを使って、指定したブロックのコードを非同期で実行できること(ただし、新しいスレッドを作るわけではなく、単にキューに入れて後から実行する)。便利な機能ではあるが、サイド・エフェクトのことを考えずに間違った使い方をするプログラマーが続出しそうで、少し心配。

        import java.lang.System;
        var saying1 = "Hello World!";
        var saying2 = "Goodbye Cruel World!";
        do later {
             System.out.println(saying1);
        }
        System.out.println(saying2);

 逆に単なるdoステートメントの方が、別スレッドを作ってdo内部のコードを実行させるように出来ている点が興味深いが、スレッドのディスパッチに関しての記述にまだあいまいさがあり、このあたりの言語仕様はまだ十分に練られていないように感じた(今後変更する可能性あり?)。

4.Update Triggerという考え方

 これはなかなか面白い。「新しいオブジェクトが作られた」とか、「オブジェクトの変数が変更された」などのイベントをキャッチして、それに対応した処理を記述できるのだ。そのためコンストラクターは不要で、代わりにこんなプログラムを書くことになる。

         class X {
              attribute nums: Number*;
         }

         trigger on new X {
              insert [3,4] into this.nums;
         }

         var x = new X();
         System.out.println(x.nums == [3,4]); // prints true

5.Incremental and Lazy Evaluation

 Haskellを知っている人には珍しくもないコンセプトだが、C++/Javaプログラマーに一口で説明するには少し難しいのがこれ。ある変数に実際の値を代入するのではなく、計算式を代入しておく機能がIncremental Evaluationだ。そうしておくと、エクセルのスプレッドシートのフォーミュラのように、参照先の変数の値が変化すると自動的に新しい値を計算し直してくれるのだ。さらに、それをlazyと宣言しておくと、その計算を実際に計算結果を参照する時まで遅らせておいてくれるのが、Lazy Evaluationである。

 Sunが提供しているサンプルは少し分かりにくいので、先の宣言型のUIを例として、このIncremental Evaluationを説明するとこうなる(注意:ここが私なりに拡大解釈してしまっている可能性がある部分)。

        label = "押してね!";
        message = "押してくれて、ありがとう";
        Frame {
              content: Button {
                   text: bind label;
                   action: operation() {
                        System.out.println(message);
                   }
              }
              visible: true
         }

とすると、上の例と同じく"押してね!"というラベルのボタンが表示されるのだが、その後、

        label = "押さないで!";
        message = "押さないでって言ったのに!";

と変数labelの値を変更するだけで、ボタンのラベルが自動的にアップデートされるのだ(再度UIを宣言し直す必要はない)。これにより、HTMLのDOMに相当するものが不要になる点が注目だ。

まとめ

 全体として見ると、コンパクトにまとまった良く出来たスクリプト言語というのが私の感想。宣言型UIは大歓迎だし、それとIncremental Evaluationの組み合わせには大きな可能性を感じる。ただし、Incremental Evaluationを実現するには、変数間の依存関係をグラフとして持っておく必要があり、そこをどのくらい効率良く実装できるかが勝負だろう。

 一つだけどうしても好きになれないのが、doステートメントが別スレッドを作ってしまう点。I/O用のバックグラウンド・スレッドの存在はプログラマーからはあえて隠し、その代わりにI/O関係のAPIをすべて非同期にした方がずっとすっきりとした言語仕様になると思う(長年UIを作る仕事をしてきたが、マルチスレッド・プログラミングとUIはものすごく相性が悪いのだ)。

Comments

n

まとめていただき、ありがとうございます。とても面白そうな言語ですね。CNetの記事を読んでも「また新しいスクリプト言語か」いった感想しか持ちませんでしたが、中島さんの記事を読んでとても興味がわきました。

非同期IOについて。IOを非同期に処理するスレッドを処理系がプログラマから隠す方式は確かに魅力的です。致命的なバグを作りこみやすい部分で、毎回同じような排他処理をプログラマがコーディングするのは生産性が悪く、かつ危険です。しかし、その代償として、全てのIO処理を必ず非同期方式で実装しなくてはならなくなると思います?例えば3つの小さな設定ファイルを読み込んでその結果何かをする処理をシーケンシャルに実装するのは容易ですが、非同期で実装するのは初心者には敷居が高いかもしれません。SUNは、初学者にとっての学びやすさを優先したのかもしれません。

tar

https://openjfx.dev.java.net/
のDemosからJavaFX Scriptの動作が試せるJava Web Startがあるんですけど、
Incremental Evaluationのサンプルは、text: bind label;のところでエラーになりました。セミコロン;は要らないようで。1行目と2行目はvarが無いとエラーになりました。

satoshi

tarさん、確認ありがとうございます。JavaFX Scriptの動作が試せるサービスがあるとは知りませんでした。さっそく試してみます。

good

ありがとうございます。
この記事により、JavaFXがわかるようになったので感謝しています。
いま、いろいろやっています。
JavaFX Scriptをやっておけば、来年頃出る予定(?)のJavaFX Mobileでも
本当に問題なく動くのを楽しみにしています。
またよろしくお願いします。

Verify your Comment

Previewing your Comment

This is only a preview. Your comment has not yet been posted.

Working...
Your comment could not be posted. Error type:
Your comment has been posted. Post another comment

The letters and numbers you entered did not match the image. Please try again.

As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

Having trouble reading this image? View an alternate.

Working...

Post a comment

Your Information

(Name is required. Email address will not be displayed with the comment.)