2017-02-15 3 views
11

私は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と呼ばれる

    1. addItemsを次のようにしているが、サブ関数

    2. サブ関数を返します。引数6で呼び出されます
    3. 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を見たのは初めてのことではありません...

  • 答えて

    18

    私の質問はなぜ矛盾ですか?

    実際にコンパイルされたILは、行動契約に関して重要ではなく、実際にはそうではありません。単一の関数にコンパイルすることで、JIT /ランタイム・レベルでの呼び出しが大幅に改善されます。

    実際に何が起こっているのかは必ずしも実際に起こっているわけではありません。「F#コードを記述して使用する際には、これがどのように推論されるべきか」です。基本となる実装は、実行時環境を最大限に活用するために、必要に応じて自由に変更する必要があります。

    +0

    可能な限り最適化することに同意します。しかし、あなたに私に何か他のことが起こっていると教えても、これは大きなコードベースで、パフォーマンス上の問題のための大きなチャンスを残すのではなく、バグを見つけにくいのですか? –

    +7

    @AnthonyRussellあなたは行動の契約に言われましたが、それは変わることはありません。コンパイラが動作が異なるためにバグが発生した場合、それはコンパイラのバグです(修正する必要があります)。ほとんどの(すべての制作品質の)コンパイルされた言語でも同様のことが起こります。コンパイラは通常、「より良い」方法で多くのコードを書き換えますが、ランタイムの動作保証と使用特性は同じです。 –

    +0

    それはすべて公平だと思うよ。迅速な対応に感謝します! –

    関連する問題