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 * factorial (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?
Recursive functions - functions that call themselves - are identified explicitly in the F# language with the rec keyword. The rec keyword makes the name of the let binding available in its body. The following example shows a recursive function that computes the nth Fibonacci number using the mathematical definition.
To find the nth term, for example, you need to know the previous term and the term before that one. This is how you can determine whether a particular function is recursive or not. If the function requires a previous term in the same sequence, then it is recursive.
The recursive functions are a class of functions on the natural numbers studied in computability theory, a branch of contemporary mathematical logic which was originally known as recursive function theory.
"Well-defined" is a somewhat fuzzy term. But here, it seems that you want to ensure that a function that is defined at 1 and then you have a recursive definition explaining how to obtain f(n) from f(n−1) does in fact lead to a function whose domain is all the natural numbers.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With