2011年8月19日金曜日

ToJSCompilerとしてのGWTについて

ToJSCompilerとしてのGWTについて 


概要
    GoogleWebToolkit GWT 
        (発音はグウィット 2009年ころにIOで突如言い出してた気がする。)

    Googleが作ったJava言語を利用したJSコンパイル技術。FWではない。
    Java to JSの変換技術。
     ToJSCompiler(てか正確にはCompile to JS かな。)

    ・Javaで記述、コンパイル結果がJavaScript(JS)として実装、実働

    ・Javaのメソッドやクラスが使える

    ・Eclipseなどと連携可能
        ステップ実行ができる、プラグインが使える、などなど
        鬼便利というかこれが肝コレだけコレが全て

    ・JUnitが使える、テストが可能

    ・JavaScript単体では書けないような範囲の物事を、
        Javaの型安全な世界で記述する事ができる

    ・JSのローディングやテストを、Javaに関連する世界で自動化できる

    ・あらかじめ用意されているライブラリがたくさん
        イベントリスナ、JSON、JSONP、
        GUI Widget(ダサい。Apple並みとは言わないまでも、、)、
        Canvas、Sound、他

    ・JSも使える Java中JS、JS中Javaが可能
        JSNI(JavaScriptNativeInterface)


落とし穴もがっちりある
    JavaかとおもったらJSだった。何を言っているかわからねーと思うが(ry

    ・変換不可能なクラスもある
        日付に関するクラスとかが無い。めんどかったんだと思うが。

    ・Widgetが破滅的にダサい
        グラフィカルな面で本当に残念です。ありがとうございます。

    ・ロードとstaticの関係
        staticなどを使うと、優先的にLoadingが組まれる。結果として、
        名前空間が効かないポイント(=衝突を考慮する必要がある部分)が生まれたりする。
        =PureJSと同じ駄目さ

        Javaであればリフレクションなどの手段で明確にアクセスできるところ、
        偶然名前が一致して衝突、などがあり得る。


    ・イベントの解除などはJSの癖を引きずる
        イベントへのアイデンティファイに対して、制約が多い。根源がJSのリスナなのでしょうがない。
        具体的には、特定のオブジェクトのみリスナから外す、という事ができない。
        オブジェクトが帰属するクラス単位でのリスナがごっそりと消える。
        (リスナのアイデンティファイについて、クラス単位より小さな単位でのアイデンティファイができない)


    ・JSNIはJSなので何が起こってもおかしく無いし補完が効かない
        オハコンの中のオワコン


ところでJavaScriptとはなんだったのか
    GWTのようなToJSCompilerが生まれた経緯を推察してみる。

    JSとは、
    HashMap a ... b
    b ( =a)
    a (=b)
    a(function b()) など。

    何でも連鎖マップに入れられ、発火させられる言語
        →他の言語でやっている様々な事が、ほぼ、JSを使って、JSの上で実装可能。


ここに闇がある
    ☆他の言語でやっている様々な事が、ほぼ、JSを使って、JSの上で実装可能。

    →言語の中に、同じ言語を使って、機能や仕組みを実装する、という行為には、元来無理がある

    だって元々その言語に無いのだもの。
    ・内部にむき出しの実装が増える事によって、トラブルが増える
        「実装した機能」それ自体の実装に触る事ができてしまう
        e.g. C++のスマートポインタ、Javaのメッセージング


    JavaScriptの場合は、元来無いものが非常に多い。
    名前空間(致命傷)、クラス、メッセージング、自己環境把握概念

    ・実装機能と自分が書き足したものとの区別がつくのは今この瞬間の書いている自分だけ
        a = a+b;        (before)
        a = a+b+c;    (after)

        →    1D後、1W後、1Y後に見て、何処が「足された部分」か、自分や他人にわかりますか? ッつー話。
    

    ・トラブルを起こさないように実装するには、階層を分けてのFW化(e.g. RoR)、ルール化が有用だが、。
        ルールが増える事(ルール爆発)は自殺行為→多彩なルールを守る事にコストがかかってしまう。
        しかもそれは永遠に続く。


    →解決策として、コンパイル という「改変」行程が選ばれる。



JSをコンパイルの結果として作りあげる技術たち ToJSCompiler

    Google Closure Tools (JS to JS コンパイル)
        http://code.google.com/closure/
        強くルール付けされた構造を模倣する事でのプラグイン化
        自己制約をパッケージ化する

    CoffeeScript (Coffee to JS コンパイル)
        http://jashkenas.github.com/coffee-script/
        JSの穴をあらかじめ殺した記法での記述と、コンパイル処理による最適化、ネームスペースの補助
        RoR3系で色々動きがあるらしいが?よく知らない。
        これからJSをどうしても書かなければ行けない分野では来ると思う。

    GWT (Java to JavaScript コンパイル)
        http://code.google.com/webtoolkit/
        Googleが用意した特定のクラス、メソッドがJSに変換される。
        コンパイル処理による最適化、パッケージによるネームスペース明示、
        staticによるシングルトン明示などができる。
        おまけでブラウザ間の差異を勝手に吸収する。
        Java言語自体に素敵さが足りないので、後述のJSCompilerたちの方が先があると思う。

    Pyjamas (Python to JS コンパイル)
        http://pyjs.org/
        触った事無いからわからん

    Js_of_ocaml
        触った事無いからわからん

    ClojureScript (Clojure to JS コンパイル)
        https://github.com/clojure/clojurescript
        さわり中 まだよくわからん

    ScalaJS (Scala to JS コンパイル ? 未登場)
        まだ無いのでわからん。作ってるらしー。 自分的に本命。
        現在のactorの挙動とか、JSフレンドリーなんじゃないかなーと思ったり。
        メソッドを渡す方法が効率的に記述できるようなバックドアが着いたら、
        ぼくのかんがえたさいきょうのげんご に近づく。
        理由は参照コピーと同義だから。


A to JavaScript の利点
    とあるA言語の能力 >>>>>> JSの能力 である前提がある。

    Aという言語があり、ルール的にJavaScriptよりも厳格 かつ、機能が定義されているとする。
    名前空間、記法制限、型、演算子、メッセージング、クラス、構造体、列挙子、、、

    これらを、その言語で書き、JSにコンパイルする。

    元々のAという言語にある機能を、Aという言語の記法で使う範囲でのみ担保すればいい。
    →最終的に出力されるJSには、手を触れる事が無い(あるとしたらA to JSコンパイラのバグとか不備)


    例えばクラスをJSで実装する場合、
    JSで直に実装→JSを書く際に、その自己定義した構造にあわせたreadとwriteが必要になる
    →ルールを言語の内側につくるので、さらに内側に書くしかない。

    他言語で書く場合
    →ルールは記述時言語側が持っているため、書き手は意識しないでいい。
    →コンパイルされた結果は、ルールが構築されたJSの中に、手続きが記述された状態になる。
    →結果は同じであっても、人が煩わされる行程が減っている、自動化できている事に注目。


ToJSCompilerとしてのGWT
    締めに、JSCompilerとしてのGWTの特性を上げる。

    ・Java記法で書ける
    ・パッケージでの名前空間の保護ができる
    ・JSNIで、JavaとJSがつなげる。JSNIは先行変換される部分記述のようなもの。
    ・最終的には結局JSに変換される

    特筆すべきは「結局JS」という部分。
        JavaとJSのハイブリッドの意味や価値がここにある。

    Pure Javaではできなかった、
    メソッドのオブジェクト化などがJava記法とJS記法の組み合わせでできる。

        private native JavaScriptObject get () /*-{

        return @com.kissaki.client.MessengerGWTCore.(略)::mtd(Ljava/lang/String;); 

         }-*/;



        これはどうよ。凄くないか。


        mtdメソッド
        public void mtd(String str) メソッドを、JavaScriptのオブジェクトに変えている。
        バリューとJavaのメソッドを関連づけたり、メソッド自体を疑似ポインタとしてぶん投げることができる。
        
        おそらく他の言語でも、JSでしかできない事を担保するために
        従来の言語の記法を拡張してブリッジにするような目論みとして、
        GWTにおけるJSNIみたいなものが出てくるはず。


        
今の俺の結論
     ToJSCompilerオハコン。
    言語の中に言語で機能を追加する副作用を回避できる。
    ブラウザで動く言語がJSに限られている事が一因だが、今後は異なるといいなーとか。JSのNativeライブラリ化とか進むといいなー。

(追記)タイトルをToJSCompilerに変えた。JSCompilerだとJSをコンパイルするように見える、と指摘受けた。11/08/23 11:40:33

0 件のコメント:

コメントを投稿

フォロワー