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(に相当するなにか)にキャストしちゃえば、全部同じように扱えるよなあ、と。
オブジェクトも、まあ、なんかうまく扱えそうな気がしてきた。(ほんとはソースなり論文探して読むなりしないとだめなんでしょうが)