HaXeがやばい件

プログラミング言語HaXeがやばい。 (http://haxe.org/)

haXe (hex と読みます) は オープンソースプログラミング言語です。

他の大部分の言語はそれぞれのプラットフォームに結びついている (Java なら JVMC# なら .NetActionScript なら Flash Player) のに対して,haXe は マルチ・プラットフォーム の言語です。

http://haxe.org/doc/intro

とイントロの最初に書いてあり、ふ〜んというのが最初の印象だったのですが、言語仕様を読み進めていくと、ほんとうに良い言語だということがわかりました。

ただ、自分もまだちょっと触っただけで本当全くわかってないので、正確な情報とかではありません。とりあえずこんなことができたよーという話。

命令形言語?

HaxeのHelloWorldを示します。
どのプラットフォームを対象とするかは本質では無いので、以下はFlash向けのコードで統一します。

package ;

import flash.Lib;

class Main 
{
	
	static function main() 
	{
		trace("hello, world!");
	}
	
}

一見すると、そのへんにある新言語と同じっぽいですが、、よく見ると型がひとつも書いてありませんね。動的型付け言語なんでしょうか??????
違うんです。実は、強い静的型付けwith型推論なんです!
なんか不穏な感じがしてきましたね。

代数的データ型

HaXeでは単にenumと呼ぶそうですが・・・。

package ;

import flash.Lib;

 enum Maybe<T> {
	Some(x : T);
	None;
}
 
class Main 
{
	
	static function main() 
	{
		var x = None;
		switch(x) {
			case Some(y) :
				trace("some data.");
			case None:
				trace("none");
		}
	}
	
}

やったー!ちょっと意地悪してみます。

package ;

import flash.Lib;

 enum Maybe<T> {
	Some(x : T);
	None;
}
 
class Main 
{
	
	static function main() 
	{
		var x = None;
		switch(x) {
			case None:
				trace("none");
		}
	}
	
}
src/Main.hx:21: lines 21-24 : Some constructors are not matched : Some

素晴らしいですね!

再帰的なデータ定義も試してみました。

package ;

import flash.Lib;

 enum Tree<T> {
	Leaf;
	Node(value : T, left : Tree<T>, right : Tree<T>);
}
 
class Main 
{
	
	static function main() 
	{
		var x = Node(1, Node(2, Leaf, Leaf), Leaf);
		print_Tree(x);
	}
	
	static function print_Tree(t) {
		switch(t) {
			case Leaf:
			case Node(v, l, r) :
				print_Tree(l);
				trace(v);
				print_Tree(r);
		}
	}
	
}

できた!!! (出力は2,1)
(しかし、これには誤魔化しがありますね。traceの型が謎です。これは僕もまだよくわかっていません。)

if文

なんか関数型言語っぽいぞこいつ・・。と思ったのでこんなのも試してみました。

package ;

import flash.Lib;
 
class Main 
{
	
	static function main() 
	{
		var x = if ("hoge" == "moja") 5 else 6;
		trace(x);
	}
	
}

コンパイルできたwwこれは嬉しい。

ファーストクラス関数

これはECMAスクリプトにあるし当然あるか。
でもアレはどうなんだ?

package ;

import flash.Lib;
 
class Main 
{
	
	static function main() 
	{
		var f = function(x,y,z) { return x * 2 + y - z; };
		var g = callback(f, 2, 3);
		trace(g(5));
	}
	
}

できたー。ただし専用の構文か。普通に書いて部分適用できるってわけには行かなかったのかな。メソッドのオーバーロードかオプション引数あたりが理由だろうか・・・?

とりあえず、

こんな所です。まだ糞なところが見つからないです。見つけるまではHaXeをやろうと思います。