このところ話題になっているHaxe(ヘックス)を使ってます。
Haxeの概要についてはWikipedia日本語版の記事が詳しいのですが、Nicolas Cannasse氏を中心に開発されているオープンソースのプログラミング言語です。C#、ActionScript 3あるいは幻のECMAScript 4に似た言語で、JavaScript、ActionScript、C++、C#、Java、PHPと多数の言語に変換して動かすことが可能であり、またそもそもそのために作られているという特徴があります。
Haxeという名前は"has a X inside"から来ているそうです。何か凄いものを持ってる、というニュアンスでいいんでしょうか? これからHaxe Foundationを立ち上げるつもりだとか、かなり気合いが入ってるようです。
で、ここ2ヶ月ほどHaxe漬けなんですが、たしかにこれは良いものだという確信が強くなってきたので、ひとつどこがいいのか書き出してみようと思いました。ユーザーが増えるといいな、という思惑で。
言語縛りから逃れられる(かも)
プラットフォーム論争というのがありますよね。PCブラウザだとこれからはHTML5一択でしょとか、Flashそう簡単に死なないよとか。スマートフォンでも、ネイティブ、ウェブ、ハイブリッド、AIR等々、あれがいい、これは駄目だと喧々諤々の議論が絶えません。
Haxeが面白いのは、これらすべてをターゲットに開発ができることです。
昨今たくさんのプラットフォームが生まれたり消えたりします。頭が痛いのは、多くのプラットフォームにプログラミング言語の縛りがあることです。あるプラットフォームを対象に書いたコードは他のプラットフォームでは動きませんし、プラットフォームが駄目になると、書いたコードが無価値になったりします。これでは、どの言語でコードを書くか、どこで頑張るかを考えるだけでも一種のギャンブルになってしまいます。後で移植する苦労を想像しながらだとキーボードを打つ手が止まってしまいます。
また、いろんな言語を書き分けていると、言語をスイッチするたびに言語仕様やごく基本的なAPI(たとえば文字列のサーチや、現在時刻の取得のような)をど忘れしていたりして、そのたびに本やノートをひっくり返したり、Google先生に質問攻めしたりするはめになって、なかなかしんどいです。
Haxeを使えば、あるいはこうしたことを解決・軽減できるかもしれません。必ずしもアプリ全体とまではいかないかもしれませんが、同一ロジックを好きな実行環境で使えます。
それどころか、PHPやNode.jsなどサーバーサイドまでHaxeで書けてしまいそうに見えます。
恐ろしいことに独自のシェーダ言語まで作っているようです。
心配になるほどの全方位作戦っぷりで、こんな試みが本当に上手くいくのか、中途半端な代物になるんじゃないかという疑問も湧いてくるのですが、意外とそうでもなく――
JavaScriptターゲットがとても実用的
最近は猫も杓子もHTML5ですが、その最大の弱点はやはりJavaScriptだと思います。この"The Trouble with JavaScript"というページがよくまとまっています。いくらThe Good Partsを読み、バッドノウハウの数々を駆使しても、素のJavaScriptで大きめのアプリケーションを作るのはきついよねということで、実際、他の言語からJavaScriptに変換するものが無数に開発されています。
が、Dart、Jangaroo、JSILその他片っ端から試してまわったんですが、CoffeeScriptのような最初からその目的で作られたものを除いて、ほとんどのトランスレータは、巨大なランタイムコードやライブラリコードを生成したり、パフォーマンス上の問題や機能制限があったりして、なかなか使いづらいです。
Haxeならそういったことはありません。最新のHaxe 2.10では、強力なデッドコード削除最適化(--dead-code-eliminationオプション)によって、ものすごくクリーンなJavaScriptコードを吐きます。Hello Worldの変換結果がたった5行です。
Haxe(Main.hx)
class Main
{
public static function main()
{
trace("Hello, World!");
}
}
実行コマンド
haxe -main Main -js output.js --dead-code-elimination
JavaScript(output.js)
var Main = function() { }
Main.main = function() {
console.log("Hello, World!");
}
Main.main();
もっと込み入ったものになっても、出力されるのは人間が書いたものに近い(バッドノウハウ混じりですが)とても素直なJavaScriptコードです。Closure Compilerなどを使ってさらに圧縮・最適化もできますし、これならモバイルでも何の不安もありません。クラスつきのJavaScript、あるいは静的型のCoffeeScriptのようなものとして普通に使えます。
ちなみに--js-modernオプションをつけるとグローバル名前空間を汚染しないようにできます。その上で、メタデータでクラスやstatic関数を外部に露出すれば、JavaScriptで使えるライブラリを作るのにも使えます。
@:keep
@:expose("com.example.MyLib.Cat")
class Cat { ... }
また、外部のJavaScriptライブラリも呼べます。基本的には静的型付けの言語ですのでexternクラスで型情報を与えたほうがいいのですが、動的型がありますので、なくてもどうにかなります。
さらにソースマップにもすでに対応しています。ブラウザ上でHaxeコードのステップ実行が可能です。
このように、JavaScriptとの親和性が高いです。クロスプラットフォームという特徴を除外して、単にJavaScript開発を楽にするためだけに使ってもHaxeは有力な選択肢だと思います。今すぐ使えます。
良い開発環境がある
HaxeはActionScriptに似た言語なので、主だったActionScriptのIDEがHaxeにも対応しています。フリーソフトで有名なのはFlashDevelopですが、Haxeでもさくさくコードを補完してくれます。WebStormでJavaScript/CoffeeScriptを書くのと比べても断然いいです。
また、IDEとは関係ないですが、静的型付けなのでコンパイル時点で多数のエラーを指摘してくれて、実行時のハマりが少ないです。素のJavaScriptの開発速度を1、CoffeeScriptが3とすれば、Haxeは5かそれ以上の感覚でしょうか(あくまで僕の場合です。個人差がありますw)。
身も蓋もないですが、要はActionScriptと同じ感覚でJavaScriptが書けます。
クラスプラットフォーム性能は本物っぽい
Box2DのHaxe版(をちょっと改造したもの)で試してみたんですが、HTML5 CanvasとFlashでほぼ同一のコードがそっくり動いています。この程度の複雑さのものが同じように動くなら心配ないんじゃないでしょうか。

*
弱点、あるいは気になる点にも触れます。
JavaScriptライブラリの利用
Haxeは静的型付けのおかげでコード補完はバリバリ効くし、エラーも迅速に指摘してくれるのですが、外部ライブラリについてその恩恵を受けるにはexternを用意する必要があります。作るのは結構しんどいです。実際、Three.jsのexternなどいろいろ作られてはいるのですが、メンテナンスが大変なのでしょう、大抵バージョンが古いです。
ただ、Dynamic型やuntypedでどうにかなるという面はあります。試しにCocos2d-html5をHaxeで無理やり使ってみました。先々月に公開されたばかりのライブラリですが、動いているようです。

この問題は静的型付けのメリットとのトレードオフで、ある意味仕方がないです。ユーザーが増えれば解決するかもしれません。
また、Haxeを実際に制作に使ってみたところ、どうせJavaScriptとの連携部分は局所化してしまうので、あまり困ることはないのではとも思いました。
Flashターゲット
Flashをターゲットにする際にはActionScriptのAPIがほぼそのまま使えるのですが、やはりAdobe純正の言語ではありませんので、つまずくところがいろいろあります。大きなものとしては、SWCのライブラリをそのまま使えなかったりします。でも、Away3DやStarlingなど普通に使えるようですし、頑張ればなんとかなるのだとは思います。どのくらい頑張る必要があるのかはやってみないと分かりませんが((追記)Starlingはライブラリで簡単に使用できるようです。コマンドラインから「haxelib install starling」で入ります)。
Away3Dのフォーラムで、後々WebGLに移植しやすそうなのでHaxeを使ってるという話を見かけて、気になっています。サポートしているOSやブラウザ、ビデオカードのドライバの範囲を考えると、しばらくはWebGLよりもStage3Dのほうが動く環境多そうですし。
クロスプラットフォームは基本的にゲーム用途
アプリケーション全体をクロスプラットフォームで制作するにはNMEというライブラリを使いますが、このライブラリは2Dゲーム用途です。
ただ、JavaScriptターゲットについては完全にJavaScriptの代わりになりますので、何にでも使えます。試していませんが、おそらくPhoneGapなりTitaniumなりも普通に使えるんじゃないかと思います。Titaniumのexternなども見かけたんですが、やっぱりちょっと古そうですかね?
ちなみに、こちらでNMEで作られたゲームが紹介されています。

NMEはネイティブ・モバイルターゲットではSDL+OpenGLベースで動作するとのことで、結構パフォーマンス高いみたいです。"haxe NME vs The World"というスライドには、C++やObjective-Cは大変、スクリプト言語はとっつきやすいがスケールしない、クロスコンパイルがスイートスポットだ、という主張があって興味深いです。
C#/Javaターゲットは実験的でまだこなれていない
試しに出力してみると、うわっと思うはずです(笑)。こちらのスライドを見ると、今後最適化していくようなので期待です。UnityやPlayStation Mobileなどにも同じコードを持っていけるようになるとすごく面白そうなんですが。
普通のfor文がない
for (i in 0...10) {}
で単純なインクリメントはできるのですが、逆方向のループやステップの変更などができません。whileを使うようにとのことです(ちなみに「...」はIntIterを作る演算子です)。やっぱり普通のfor文要るんじゃない? という話になっていたりするので、そのうちつくのかもしれません。
演算子オーバーロードがない
個人的な趣味です。ゲームで多用するベクトルや行列などを扱うには欲しいなあと……でもいろいろ難しそうですね(関連:Dartの演算子オーバーロードを使ってみる)。
日本語の情報が少ない
仕方ないですねー。このエントリでほんのちょっとだけ増えたでしょうか。
(追記)terurouさんがJavaScript開発向けのチュートリアルを現在執筆されています。力作です。
*
というところで、使い込むと細かな問題がもっと出てくるのでしょうが、全体としてかなり好感触な言語環境です。あまりにできることが多くて、まだ全容がまったく見えないのですが。
ここしばらく、HTML5で楽にゲーム作るにはどうするんだとあれこれ不毛な試行錯誤を続けていたんですが、少なくとも言語面ではHaxeがひとつの有力な落ちつき先になりそうです。ここに自作ライブラリを構築していこうという気分になっています。JavaScript出力言語として非常に良好な上に、ネイティブやFlash、サーバーサイドまでターゲットにできるなら隙がなさそうじゃないですか? FalconJSも気になるんですが、今年中には出てこない雰囲気のようで……。
独断と偏見ですが、Unity(ゲームエンジンのほうの)とHaxeは当代2大チート技術だと思います。haxe.orgのはてブコメントに「オーバーテクノロジー過ぎて逆にあまり評価されてない」とあって面白いなと思いました。自分も名前だけは耳にしていましたし、FlashDevelopの新規プロジェクト作成ウィザードにHaxeのプロジェクト群が並んでるのをずっと見ていたはずなんですが、こんなものが着々と作られていようとは思いませんでした。
そんなわけで、ざっくりとHaxe凄いよ面白いよという話でした。おすすめです。