私はF#を勉強しようとしています。新しいことを学ぶときに、私はILの中で何が起こっているのかを見るのが好きです。私は最近、その言語の明白な基本である「カリング」について読んだ。あなたは以下の関数を作成F# for fun and ProfitによるとなぜF#は別の関数にカリングをコンパイルしないのですか?
:作成される2つの引数の関数があります本当に起きているのである
let addItems x y = x + y
。
let addItems x =
let subFunction y =
x + y
subFunction
、あなたはaddItems 5 6演算の順序で関数を呼び出す際に、引数5
addItemsと呼ばれる
addItemsを次のようにしているが、サブ関数
- サブ関数を返します。引数6で呼び出されます
- subFunctionはスコープsの引数5を持ちますo 5と6の合計を加算して返します。
これはすべて表面上で問題ないです。しかし、これについてILを見ると、別の話があります。
.method public static int32 testCurry(int32 x,
int32 y) cil managed
{
.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = (01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00)
// Code size 5 (0x5)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: add
IL_0004: ret
} // end of method Sandbox::testCurry
2つの引数をとり、Int32を返す1つの静的関数が明確にわかります。
私の質問は、なぜ矛盾ですか?私がILを見たのは初めてのことではありません...
可能な限り最適化することに同意します。しかし、あなたに私に何か他のことが起こっていると教えても、これは大きなコードベースで、パフォーマンス上の問題のための大きなチャンスを残すのではなく、バグを見つけにくいのですか? –
@AnthonyRussellあなたは行動の契約に言われましたが、それは変わることはありません。コンパイラが動作が異なるためにバグが発生した場合、それはコンパイラのバグです(修正する必要があります)。ほとんどの(すべての制作品質の)コンパイルされた言語でも同様のことが起こります。コンパイラは通常、「より良い」方法で多くのコードを書き換えますが、ランタイムの動作保証と使用特性は同じです。 –
それはすべて公平だと思うよ。迅速な対応に感謝します! –