Using the following in the F# interactive console, it ran in less than a second:
let rec f i l =
match i with
| i when i < l -> f (i+1) l
| _ -> l
f 0 100000000;;
I then tried a straight translation i.e.
let rec g i l = if i < l then g (i+1) l else l
g 0 100000000;;
Same outcome but different compilation.
This is what f looks like in when translated to C#:
int f(int i, int l)
{
while(true)
{
int num = i;
if(num >= l)
return l;
int i = num;
l = l;
i = i + 1;
}
}
g, however is translated to this:
int g(int i, int l)
{
while(i < l)
{
l = l;
i++;
}
return l;
}
It is interesting that two functions that are fundamentally the same are rendered differently by the F# compiler. It also shows that the F# compiler has tail-recursive optimization. Thus this should loop until i reaches the limit for 32-bit integers.