F# Code Execution Order

夙愿已清 提交于 2020-01-03 08:34:13

问题


another noob question regarding F#.

If I have the following code...

let ExeC =
    printfn "c"
    3

let ExeB b = 
    printfn "b"
    2

let ExeA = 
    printfn "a"
    1

printfn "Example %d " ExeA
printfn "Example %d " (ExeB 1)
printfn "Example %d " ExeC

The output is as follows...

c
a
Example 1
b
Example 2
Example 3

What seems unusual here is the order that the code is executing in. In a previous question Brian mentioned something about expressions, I was hoping someone could explain this a bit more. It almost seems like the compiler is intelligently pre-executing things to calculate values... but I don't know?


回答1:


ExeA and ExeC aren't functions, but single values. The compiler ensures that values initialise in the order in which they're declared in the source file, so what's happening here is:

  1. ExeC initialises
  2. ExeA initialises
  3. Example 1 is printed, using ExeA's initialised value
  4. The ExeB function is called as normal
  5. Example 3 is printed, using ExeC's initialised value

If you want ExeA and ExeC to be truly lazy -- that is, to control when their side effects run -- you could turn them into functions that accept unit:

let ExeC () =
    printfn "c"
    3

let ExeB b = 
    printfn "b"
    2

let ExeA () = 
    printfn "a"
    1

printfn "Example %d " (ExeA ())
printfn "Example %d " (ExeB 1)
printfn "Example %d " (ExeC ())



回答2:


As a follow up to Tim's answer, I thought you might appreciate some further insight into what you've stumbled upon. In your example, ExeC and ExeA take advantage of the functional style of organizing code through lexical scoping and closures. Let me demonstrate a more powerful example.

let calc n =
    //...
    let timesPieDiv4 = 
        let pie = 3.14
        let pieDiv4 = pie/4.
        n * pieDiv4

    //...

Here again timesPieDiv4 is not a function, but does have a body which contains a series of sub calculations which are not exposed to the rest of the calc function. In a language like C#, you have two options neither of which appeals to me. The first option is to simply declare pie and pieDiv4 within the main body of calc, but then it's less clear how they are being used and you dirty your variable space. The other option is to factor those sub calculations out into a separate private helper function. But I dislike such functions, because with many it becomes hard to analyze your complex algorithms since you are constantly darting around looking up various implementation pieces. Plus it's a lot of boiler plate code and value passing. That's why F# functions are "public" by default, lexical scoping and closures allow you to hierarchically organize "private" functions and values within your public facing functions.



来源:https://stackoverflow.com/questions/3170951/f-code-execution-order

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!