Haxe

**Haxe**（ヘックス、発音記号は /heks/）はオープンソースの高級プログラミング言語、もしくはそのコンパイラである。

言語としてのHaxeは静的型付きのオブジェクト指向言語であり、構文はActionScript 3および標準化が中止されたECMAScript 4に似ている。Adobe FlashやJava仮想マシンおよび独自のNekoやHashLinkで実行可能なバイトコードにコンパイルされるほか、JavaScript、ActionScript 3、C++、Cppia、C#、Java、PHP 7、Python 3、Luaへのソースコードの変換が可能であるため、主にマルチプラットフォーム開発を目的として使用される。また、FlashからHTML5への移行にも適する。

2012年4月に表記がhaXeからHaxeに変更された。

## 対応プラットフォーム
Haxeのコンパイラは、AVMやJava VM、そして独自の仮想マシンであるNeko及びHashLinkのバイトコードや、JavaScript、ActionScript 3、C++、Cppia、C#、Java、PHP、Python 3、Luaのソースコードを生成する。複数のプラットフォームに「コンパイルする」この戦略は、"Write once, run anywhere" の思想に基づいている。これにより、プログラマが目的のために最良のプラットフォームを選択できる。

Haxeでは、これらプラットフォームは「ターゲット」と呼ばれる。

### AVM
haXe Betaより対応（2006年2月）。バイトコードへコンパイルされる。主な想定プラットフォームは、Adobe Flash、Adobe AIR。

2007年3月、AVM2へ対応した。

### Neko
haXe Betaより対応(2006年2月)。バイトコードへコンパイルされる。

### JavaScript
1.0より対応(2006年5月)。単一のソースファイルを出力する。主な想定プラットフォームは、ブラウザやNode.js、Electron。

Dynamic型によってJavaScriptのライブラリをそのまま利用できるほか、著名なライブラリであれば、Haxelibに公開されている(あるいは自分で定義した)externライブラリを使用することで、型安全性を保ったまま利用することができる。

Haxe 4.0現在、ECMAScript 5に準拠したコードへコンパイルされる。加えて、4.0以降ではECMA Script 6から追加されたクラス定義に対応した。

### ActionScript 3
1.xより対応（2007年3月）。複数のソースファイルを出力する。主な想定プラットフォームは、Adobe FlashやAdobe AIR。

### PHP
2.0.0より対応（2008年7月）。複数のソースファイルを出力する。

Haxe 3まではPHP 5.1.0に準拠したコードへコンパイルされていたが、Haxe 4以降ではPHP 7.0.0へ変更された。

### C++
2.4.0より対応（2009年7月）。複数のソースファイルを出力する。主な想定プラットフォームは、WindowsやmacOS、Linux、iOS、Android、Tizen、BlackBerry。

C++ターゲットを利用するには、Haxelibに公開されているhxcppライブラリのインストールが必要となる。また、独自のガベージコレクション機能を実装している。

### C#
2.10.0より対応（2012年4月）。複数のソースファイルを出力する。主な想定プラットフォームは、.NET FrameworkやMono、ASP.NET、Unity。

Haxelibに公開されているhxcsライブラリによって、.NET Framework 2.0及び4.0の標準ライブラリを利用できるようになる。.NET Frameworkのパスを指定すれば、任意のバージョンを利用することも可能。

### Java
2.10.0より対応（2012年4月）。複数のソースファイルを出力する。

Haxelibに公開されているhxjavaライブラリによって、Java 8の標準ライブラリを利用できるようになる。

### Python
3.2.0-rc.2より対応（2015年5月）。単一のソースファイルを出力する。

### Cppia
3.2.0-rc.2より対応（2015年5月）。単一のスクリプトファイルを出力する。

Cppiaは、外部のコンパイラを必要としない、Haxe上で完結するC++のスクリプト実行機能を提供する。Haxelibで公開されているhxcppライブラリを必要とする。

### Lua
3.3.0-rc.1より対応。単一のソースファイルを出力する。

### HashLink
3.3.0-rc.1より対応。バイトコードへコンパイルされる。主な想定プラットフォームは、WindowsやmacOS、Linux、iOS、Android、Nintendo Switch、PlayStation 4。

### Java VM
4.0.0-rc.3より対応。バイトコードへコンパイルされる。

## 言語
静的型付きのオブジェクト指向言語である。HaxeはActionScriptから派生した言語であるため、基本構文はActionScript3と共通する部分が多い。

### 機能

#### ActionScript3と共通する機能
HaxeはActionScript3が持つような以下の機能を持つ。

* クラス、インタフェース
* プロパティ
* パッケージ、モジュール機構
* アクセス修飾子（ただし、publicとprivateの2段階のみ）
* ローカル関数、第一級関数オブジェクト、クロージャ
* 各種演算子（算術、代入、論理、文字列、条件、ビット）
* リフレクション

これらの機能は、クラスのようにActionScript3とよく似た構文で提供されるものもあるが、プロパティのようにActionScript3とは異なる文法で提供されるものもある。

##### ActionScript3との相違点
構文が似ていても細かい挙動がActionScript3と異なるものも多い。以下にそのようなHaxeの挙動をいくつか挙げる。

* if文、switch文、ブロックが式であり、値を返す。
* ローカル変数、関数のスコープが異なる。
* privateのアクセス修飾子の意味合いが、ActionScript3のprotectedに相当する。
* 演算子の優先順位が異なる。
** % が * と / より優先度が高い。
** |、&、^の優先度が同じ。
** |、&、^が、==、!=より優先度が高い。

また、ActionScript3にはあるがHaxeには存在しない機能もある。以下にその例を挙げる。

* for(初期化式; 継続条件式; 再初期化式){} のC言語形式のfor文

#### 独自の機能
その他、以下のような独自の機能を持つ

* 型推論
* 型パラメータ（ジェネリクス）
* インライン関数
* 列挙型（一般化代数的データ型）
* 型エイリアス (typedef)
* パターンマッチング
* 構造的部分型付け
* 関数の部分適用
* 条件付きコンパイル
* 配列内包表記、辞書内包表記
* 文字列リテラル内での改行、文字列内の変数展開（ヒアドキュメント）
* 静的拡張 (Mixin)
* マクロ

### 型システム
Haxeでは細かい型宣言が可能である。


```haxe
function func1(threeDimensionalArray:Array<Array<Array<Int>>>, string:String, bool:Bool) { ... }

// オプションのInt整数値を渡し、Intを返す
function func2(?i:Int):Int {
    return 0;
}

// 引数のない関数をパラメータとして渡す
function func3(f:Void -> Void) {
    f();
}

// Intを渡しIntを返す関数をパラメータとして渡す
function func4(f:Int -> Int) {
    var result = f(1);
}

// 任意型を取り、任意型を返す
function func5(d:Dynamic):Dynamic {
    return d;
}
```


Haxeは静的型付き言語であるが、Dynamic型やuntypedを用いることで部分的に型チェックを無効化できる。逆にexternクラスによる型定義を行うことで、動的型のターゲットのライブラリに対して型チェックを有効にして連携できる。

#### 列挙型
列挙型 (enum) はHaxeの重要な特徴である。

Haxeの列挙型は他の多くの言語のように単に値を列挙して識別子をつけるものよりも抽象的で、列挙子（Haxeではenumコンストラクタと呼ぶ）ごとに異なるパラメータつことが可能である。このような列挙型はMLやHaskellのような言語の代数的データ型に相当する。

これにより、自身をパラメータにもって再帰構造をつくったり、木構造を作ったりできる。

以下の例のようにインスタンス化して使う。


```haxe
enum Color {
    red;
    green;
    blue;
    rgb: (r:Int, g:Int, b:Int);
}
 
class Colors {
    static function toInt(c:Color):Int {
        return switch (c) {
            case red: 0xFF0000;
            case green: 0x00FF00;
            case blue: 0x0000FF;
            case rgb(r, g, b): (r << 16) | (g << 8) | b;
        }
    }
    static function validCalls() {
         var redint = toInt(Color.red);
         var rgbint = toInt(Color.rgb(100,100,100));            
    }
}
```


### 標準ライブラリ
Haxeの標準ライブラリはすべてのターゲットで動作するもの、すべてでは無いが複数のターゲットで動作するもの、個別のターゲットのみで動作するものがある。以下にそれぞれの例をあげる。

* すべてのターゲットで動作するもの
** バイナリ操作
** ZIP圧縮、解凍
** テンプレートエンジン
** JSONの書き出し、読み込み
** ユニットテスト
** Base64のエンコードとデコード
** 正規表現（ターゲットごとで細かい動作は異なる）
* すべてではないが複数のターゲットで動作するもの
** 標準入出力、標準エラー出力（Flash、JavaScript以外のターゲット）
** SQLを操作するライブラリ (Neko, C++, PHP)
* 個別のターゲットで動作するもの
** Flash、Java、C#、PHP、Pythonのそれぞれのターゲットの標準のAPI
** HTML5標準のAPIおよびjQueryのextern (JavaScript)
** AST（抽象構文木）やコンパイルのオプションの操作（）

このように機能それぞれに合わせた抽象化が行われているため、複数のターゲットで動作するような書き方と、個別のターゲットに依存してそのターゲットの利点を生かすような書き方の両方ができる。

#### JavaScript
個別のターゲットのに依存する場合の例として、JavaScript出力におけるHTML5 Canvasの使用例を示す。


```haxe
import js.Browser;
import js.html.CanvasElement;
 
class Main 
{
    static public function main()
    {
        var canvas:CanvasElement = cast Browser.document.getElementById("canvas");
        var ctx = canvas.getContext2d();
		
        ctx.fillStyle = "#F00";
        ctx.fillRect(50, 50, 100, 100);
    }
}
```


### サードパーティーのライブラリ
#### OpenFL
HaxeではFlashターゲットの場合はFlashのAPIをそのまま使用できるが、他のターゲットについてもFlashに類似したオープンソースのAPI (OpenFL) が開発されている。

クロスプラットフォームのライブラリであるOpenFLを用いて画像を表示するプログラムを示す。同一コードがFlash、HTML5、Windows/Mac/Linux/iOS/Androidネイティブで実行可能である。描画には、FlashではDisplayObject、HTML5ではWebGLまたはCanvas、ネイティブ環境ではOpenGLが使用される。


```haxe
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.Lib;
 
class Main extends Sprite 
{
    public function new() 
    {
        super();
 
        var image = new Bitmap(openfl.Assets.getBitmapData("img/sample.png"));
        addChild(image);
    }
 
    static public function main() 
    {
        Lib.current.addChild(new Main());
    }
}
```


## コンパイラ

### 実装
HaxeのコンパイラはOCamlで実装されている。Haxeの利用者にはOCamlの知識は必要ない。

### 機能
Haxeのコンパイラは複数のプラットフォームへのコンパイルの他に以下のような機能を持つ。

#### ターゲット共通
* デッドコード削除
* 定数畳み込み
* リソースデータの埋め込み
* IDEに対してコンパイル・補完・リファクタリング機能を提供するサーバ機能
* ドキュメント生成用のXml出力

#### 各ターゲット個別
* SWC、SWFのライブラリの利用（Flash）
** 静的リンク・動的リンク
** SWC、SWFのライブラリからのexternの生成
** SWCファイルの生成
* ソースマップの生成（JavaScript）
* jarライブラリの利用（Java）
* dllライブラリの利用（C#）

## 統合開発環境
Haxeでのプログラミングには各種の統合開発環境 (IDE) およびエディタが利用できる。Haxeのコンパイラには、IDEに対してコンパイル・補完機能を提供するサーバ機能が備わっている。
* FlashDevelop
* Visual Studio Code - プラグイン
* Sublime Text - Haxeバンドル
* Atom - atom-haxe
* Vim - Vaxe
* IntelliJ IDEA - 公式プラグイン
* FDT

## Haxeで書かれたソフトウェア
Flashコミュニティを出自とする言語のため、ゲームの用例が多い（言語上はそれに限定されない）。以下に代表的なものを挙げる。

* Evoland - Haxe創始者（Nicolas Cannasse）ほかによるインディーRPG
* Papers, Please - 架空の共産国の入国審査官を疑似体験するゲーム。OpenFLを使用。Metacriticのメタスコア85を獲得。GDC 2014のIndependent Games Festivalにおいて最優秀賞を受賞。
* OpenFL - Showcase - OpenFLを使用したゲームのショーケース
* Stencyl - 2Dゲームエディタ。OpenFLを使用。
* TiVo - Android、iOS、デジタルビデオレコーダのアプリケーションに使用している。

## 歴史
開発当初から現在まで、Nicolas Cannasseがプロジェクトのリーダーを務める。ActionScriptの代替コンパイラとして開発されたため、Flashターゲットの用途が多かったものの、現在はプラットフォーム中立な言語環境となることを目指している。

* 2005年 10月 フランスのブラウザゲーム開発会社の独自ActionScriptコンパイラMTASCの後継プロジェクトとしてHaxeが誕生（当初の綴りはhaXe）
* 2006年 5月 Haxe 1.0がリリース、JavaScriptターゲットに対応
* 2008年 7月 Haxe 2.0がリリース、Franco PonticelliによりPHPターゲットが追加
* 2009年 7月 Haxe 2.04がリリース、Hugh SandersonによりC++ターゲットが追加
* 2011年
** JavaScriptターゲットのメンテナとして参加したBruno Garciaにより、2.08と2.09のリリースにおいてJavaScriptターゲットの最適化が行われた
** Simon Krajewskiがチームに参加
** Cauê WaneckによりJavaおよびC#ターゲットが追加
* 2012年 
** 4月 パリ開催のWorld Wide Haxeカンファレンスにおいて、表記をHaxeに変更すること、次のメジャーバージョンとなるHaxe 3に向けて破壊的変更を行うことがアナウンスされる
** Nicolas CannasseがMotion Twinより独立、インディーゲーム開発会社およびHaxe Foundationを設立
* 2013年 5月 Haxe 3.0がリリース

## 言語名の由来

Haxeの名前は、短くシンプルで使われていないこと、また新しい技術を成功に導くために必要な X を中に持っていること（has a X inside）から命名された。

当初の綴りはhaXeであったが、2012年4月のWorld Wide Haxeカンファレンスにおいて、表記を固有名詞として馴染みやすいHaxeに変更することがアナウンスされた。

## よく比較される言語
HaxeはJavaScript生成言語（いわゆる「altJS」）のひとつとしてしばしば言及される。比較対象となる主な言語として、以下が挙げられる。

* CoffeeScript
* TypeScript
* Dart
* JSX

## HashLink
HashLinkは、Nekoの後継とされる新しい仮想マシンで、2016年10月20日に開催された"London Haxe Meetup 20th October 2016"にて発表された。x86及びx86-64のWindows、macOS、Linux上で動作する。DirectXやSDL、OpenALをベースとしたマルチメディア機能のほか、zlibなどの著名なライブラリを内包する。またWindows限定ではあるが、一部のネイティブGUIコンポーネントも利用できる。なお、Neko VMとは異なり静的型付けである。実行にはHashLinkバイトコードファイル(拡張子は`.hl`)を用いる。

HashLinkの動作形態として、**HL/JIT**方式と**HL/C**方式の2種類がある。HL/JIT方式では、実行時コンパイラを通して仮想マシン上で動作させる為、コンパイル速度が高速でデバッグに向いている。一方、HL/C方式では仮想マシンは使用されず、代わりにC言語ソースコードを出力する。出力されたCソースコードは、任意のCコンパイラでビルドでき、より高いパフォーマンスと移植性が期待できる。例えば、iOSやAndroidなどのモバイルOS、PlayStation 4やNintendo Switchなどの家庭用ゲーム機といった、デスクトップ環境に限定されない様々なプラットフォームへの移植が比較的容易となる。実例として、このHashLinkとゲームエンジンであるHeapsで開発されているMotion Twin社のDead Cellsは、PlayStation 4、Nintendo Switch、Xbox One向けに移植されている。

## 脚注


## 外部リンク
* 公式Haxeウェブサイト
** Try Haxe! - Web上でHaxeの動作を確認できる実行環境
* OpenFL - Haxeのゲーム用マルチプラットフォームライブラリ
** ActionScript3とHaxeを比較したチートシート