C#に逆コンパイルしてみる

let f g x = ignore(g x)

let _ = 
	f ((+) 1) 2;
	f ((^) "Hello") "F#"

を、.Net Reflectorを使ってC#に変換。すると、mainとfという関数ができている。

public static void f(FastFunc g, object x)
{
      object obj1 = g.Invoke(x);
      Pervasives.ignore(obj1);
}

public static void _main()
{
      int num1 = 1;
      FastFunc func1 = new File1.clo@4(num1);
      num1 = 2;
      File1.f(func1, num1);
      string text1 = "Hello";
      FastFunc func2 = new File1.clo@5(text1);
      text1 = "F#";
      File1.f(func2, text1);
}

ほおー、全部objectにキャストして扱ってるのか。なるほど、型検査を通ったプログラムなら、型エラーはでない(はずな)んだなあ。

同時に、積年の疑問が少しだけ解決。OCamlとかでは、全ての値はオブジェクトとしてヒープに格納されGCが面倒を見ることになっている。これなら、マシン語コンパイルする場合も、.netと同様にobject(に相当するなにか)にキャストしちゃえば、全部同じように扱えるよなあ、と。

オブジェクトも、まあ、なんかうまく扱えそうな気がしてきた。(ほんとはソースなり論文探して読むなりしないとだめなんでしょうが)