Haxe とは、プログラミング言語である。公式サイト
ちょっとだけ使ってみたので、感じたことを書きなぐっておく。
特徴
複数の言語にコンパイルできる(ターゲット一覧):
- Flash (bytecode) / ActionScript
- 言語仕様は ActionScript の影響を色濃く受けているっぽい
- JavaScript
- PHP
- Java, C#, C++ などの静的言語
- 他
良いところ
- 代数的データ型(enum)とパターンマッチ(switch 式/文)がある。
- Haskell で言うところの newtype みたいなやつ(abstract)がある。
- インライン関数がある。
- 実行時コストを気にすることなく another level of indirection を導入できる。
- 条件コンパイルと併用するといい感じに環境の違いを吸収できそう。
- マクロがある。
- 実際どの程度強力かは、あまり使い込んでいないので何とも…。
悪いところ
- Java のように、すべての関数をクラスの中に書かないといけない。main 関数はどこかのクラスの static 関数で定義する。
- Java のようにと言うか、直接的には ActionScript から受け継いだ仕様っぽい。
- 型クラスや deriving がない。
- 代数的データ型を
==
で比較できないのが地味に辛い(Haskell ならderiving Eq
をやっておけば==
で比較できる)。Type.enumEq は、中に enum じゃない物が入っていた場合==
で比較してしまうみたいなので、オブジェクトへの参照を含む enum どうしの比較が辛いことになる。 - null の扱いがイマイチ。動的ターゲットと静的ターゲットによって微妙に違う。
- Option<T> 型と Null<T> 型のどちらを使うか迷う。
- NonNull<T> みたいなものが欲しい。
- 標準ライブラリの細かい仕様が、ターゲットに依存する場合がある。具体的には正規表現の EReg。
- Write once, debug everywhere と言う感じ。
- ターゲット依存の挙動を排除するために標準ライブラリの実装を肥大化させるか、ターゲット依存の挙動を許して標準ライブラリの実装をスリムにするかのトレードオフなので、やむを得ない面はある。
- 条件コンパイル(
#if
〜#elseif
〜#else
〜#end
)が使えるので、適宜切り分けるべし。
- 簡単なデータ型を作る時に、クラス型か anonymous struct 型か(enum 型か)悩む。
- Static extension を使えば、 anonyomous struct 型や enum 型にもメソッドを追加できる。
- 構築方法が
new Hoge(33, 4)
/{foo: 33, bar: 4}
/Hoge(33, 4)
という風に違うが、 abstract を使えば吸収できそう(全部new Hoge
の形で構築できるようになる、はず)。 - 静的言語がターゲットの場合、 anonymous struct 型は効率が悪そうに見えるので避けるべきかもしれない。
- 一方、 JavaScript がターゲットだとクラスよりも anonymous struct の方が良いのか…?と思ったり。
各ターゲットに関して
- JavaScript
- 等値比較を
===
ではなく==
でやっているのがイケてない。null
/undefined
との比較ならともかく、数値とか文字列とかは===
で良くないか。
- 等値比較を
- C++
- 動的言語って感じのソースコードを吐き出す。
- クラスのメタデータ満載。名前(文字列)によるフィールドへのアクセスとか。
- Structural subtyping や(C++ ではなく Haxe の)RTTI を使わない場合にこいつらを抑制する手段はないのか。
- 行番号やスタックの変数の情報と思われるもの(
HX_STACK_LINE
,HX_STACK_VAR
)はコンパイルオプションの-no-debug
で抑制できる。 Null<Int>
がDynamic
になってる。- 全体的に、もっと静的言語っぽいソースコードを吐き出す余地はあると思う。
- 動的言語って感じのソースコードを吐き出す。
まあ、手書きのコードには敵わないにせよ、知らないターゲット言語でも「とりあえず動く」ものを吐き出せるというのはすごいと思う(null の扱いの違いや正規表現の非互換に目をつぶれば)。