2017-02-15 12 views
11

그래서 나는 F #을 배우려고 노력하고 있으며, 새로운 것들을 배우면서 나는 일리노이를보고 어떤 일이 일어나고 있는지를보고 싶어합니다. 나는 최근에 언어의 분명한 기초 인 Currying에 대해 읽었습니다. 당신이 아래의 함수를 만들 F# for fun and Profit에 따르면왜 F #은 커리를 분리 함수로 컴파일하지 않습니까?

: 생성되는 두 개의 단일 인수 함수가 정말 무슨 일이 일어나고있다

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에는 범위 5에 인수 5가 있습니다. o 5와 6의 합을 더하고 반환합니다.

    이 모든 것이 표면에서 들립니다. 그러나 이것을 위해 일리노이를 보면 다른 이야기를 들려줍니다.

    .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 
    

    두 개의 인수를 사용하고 Int32를 반환하는 단일 정적 함수가 생성되었음을 명확하게 알 수 있습니다.

    제 질문은 왜 불일치입니까? 내가 IL을 보았을 때 처음에는 설명서가 없는데 ...

  • 답변

    18

    제 질문은 왜 불일치입니까?

    실제로 컴파일 된 일리노이는 행동 계약의 관점에서 중요하지 않아도되고 실제로는 그러지 않아야합니다. 단일 함수로 컴파일하면 JIT/런타임 수준에서 호출의 최적화가 훨씬 향상됩니다.

    "실제로 무엇이 일어나고 있는지 ..."는 반드시 실제로 일어나고있는 것은 아니며, "F # 코드를 작성하고 사용할 때 이것이 어떻게 추론되어야하는지 ..."입니다. 런타임 환경을 최대한 활용하려면 기본 구현을 필요에 따라 자유롭게 변경해야합니다.

    +0

    가능한 한 많이 최적화해야한다는 것에 동의합니다. 그러나 한 가지를 말하면서 다른 일이 일어나고 있다고 말할 때 큰 코드 기반에서 성능 문제가 발생하거나 버그를 찾기가 어려울 수 있습니다. –

    +7

    @AnthonyRussell 당신은 행동 계약서에 대해 이야기 할 수 있습니다. 컴파일러가 동작이 다르기 때문에 버그가 발생하면 이는 컴파일러 버그입니다 (수정해야 함). 대부분의 (모든 프로덕션 품질의) 컴파일 된 언어에서도 비슷한 일이 발생합니다. 컴파일러는 일반적으로 "더 나은"방식으로 많은 코드를 재 작성하지만 런타임 런타임의 동작 보장 및 사용 특성은 동일하게 유지합니다. –

    +0

    좋아, 그거 모두 공평 해. 빠른 답변 주셔서 감사합니다! –