开发者

What's the reason of marking a recursive function as rec in F#?

I am not sure if this is a stupid question but I was going through the tutorial that comes with VS 2010 and there is a function like this:

let rec factorial n = if n=0 then 1 else n * fac开发者_运维百科torial (n-1)

What's the reason of this recursive function to be marked with the rec keyword?

Is it so that the compiler is assured of it being recursive so can do certain optimizations?

What happens if you exclude it?


This might be instructive:

let Main() =
    let f(x) = 
        printfn "original f: %d" x
    let f(x) =
    //let rec f(x) =
        printfn "entered new f: %d" x
        if x > 0 then
            f(x-1)
        else
            printfn "done"
    f(3)
Main()

That prints

entered new f: 3
original f: 2

Now if we comment out let and uncomment let rec, then it prints

entered new f: 3
entered new f: 2
entered new f: 1
entered new f: 0
done

So from that point of view, it's just about name binding; let rec puts the identifier in scope immediately (in this example, shadowing the previous f), whereas let puts the identifier in scope only after its body is defined.

The motivation for the rule does stem from interactions with type inference.


According to Chris Smith (works on the F# team) -

It's to inform the type inference system to allow the function to be used as part of the type inference process. rec allows you to call the function before the type inference system has determined the function's type


According to the MSDN, it's only a syntatic necessity:

Recursive functions, functions that call themselves, are identified explicitly in the F# language. This makes the identifer that is being defined available in the scope of the function.

http://msdn.microsoft.com/en-us/library/dd233232.aspx


What's the reason of this recursive function to be marked with the rec keyword?

To tell the compiler that any uses of the function name inside the body of the function refer to it recursively rather than to a previously-defined value of the same name.

Is it so that the compiler is assured of it being recursive so can do certain optimizations?

No.

What happens if you exclude it?

You lose the ability for the function you are defining to refer to itself in its function body and gain the ability to refer to previously-defined values of the same name.


It's necessary so that the function can be recursive. A non-rec function only knows about bindings at the place where it's defined, not after (so it doesn't know about itself).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜