JSXよりHaxeがイケてる3つの理由
Javascriptを生成できる言語『JSX』がリリースされました。めでたいですねー。
ただ同じくJavascriptを生成きるHaXeのことが忘れられている気がするので、宣伝します。 ステマじゃないよ!
型推論がイケてる
現時点でJSXには型推論が実装されてないので、関数を定義するには全ての型を書く必要があります。
// JSXだよ! function add(x : number, y : number) : number { return x + y; }
これだけなら特に問題ないように見えますが、これが高階関数を定義しようとするとどんどん複雑になっていきます。
// JSXだよ! function f(g: function(:number):number): function(:number):number { return function(x: number): number { return g(x+1); }; }
一方、Haxeには型推論が実装されているので、上記のコードから大部分の型注釈を省略できます。
// Haxeだよ! function add(x,y) { return x + y; } function f(g : Int -> Int) { return function(x) { return g(x+1); } }
文法がほどんど変わらないにもかかわらず、型推論ができるのでイケてます。
型が柔軟
Haxeの型システムはとても柔軟なので、静的型付けの安全性を損なうことなく、様々なコードを書くことができます。
ジェネリクスはそのうちJSXに入るでしょうし、enumのすばらしさについてはbleisさんがすでに書いているので、ここでは省略して構造的部分型について解説します。
まず、こんな感じのPersonクラスがあったとします。名前と性別を持っています。
// Haxeだよ! class Person { public var name : String; public var gender : String; public function new(name : String, gender : String){ this.name = name; this.gender = gender; } }
また、こんな感じのBookクラスもあります。名前だけを持っています。
// Haxeだよ! class Book { public var name : String; public function new(name : String){ this.name = name; } }
このPersonクラスとBookクラスは共通のnameフィールドを持っていますが、継承関係がないのでnameフィールドを取り出す関数を書けないような気がします。
function getName(x : ????) { return x.name; }
しかしHaXeでは、「nameというフィールドを持ったオブジェクト」を表わす型を扱うことができます。これは構造的部分型と呼ばれます。これを使うと、下記のようなコードを実現できます。
// Haxeだよ! // String型のnameフィールドを持つオブジェクトを受け取り、そのnameフィールドを取り出す関数 function getName(x : { name : String}) { return x.name; }
同程度の速度で動く
JSXの速さのキモはインライン展開らしいです。
一方、Haxeにはinlineキーワードがあるので任意の関数をinline展開するよう指定できます。 インライン展開できない関数に対して指定した場合は、コンパイル時にエラーになります。
// HaXeだよ! inline static function getName(x : { name : String } ) { return x.name; }
inlineキーワードを適切に指定することで、AOBenchをJSXと同等程度の速度で動作させることができるそうです。
まとめ
- Haxeはイケてる言語だよ
- こんな機能がJSXにもはいるといいなぁ
おまけ
速度比較をするためにaobenchをHaxeに移植したのですが、一晩のうちにチューニングによりHaxeがJSXを抜き、その翌日にJSXコンパイラが修正されて再び抜かれる、という流れが一日でおこりました。JSXは進化が速くてすばらしいです。 → JSX v.s. HaXeベンチマーク戦争 - Togetter