There's some discussion of it here: http://stackoverflow.com/questions/15864670/generate-tail-call-opcode
In particular, look at Tomas Petricek's answer (he is an F# MVP). It appears the F# compiler (in release mode) does give guarantees about tail-recursion (it's the C# compiler that cannot). Here's the blog post from the Visual Studio F# team on it (although it's getting old now): http://blogs.msdn.com/b/fsharpteam/archive/2011/07/08/tail-calls-in-fsharp.aspx On 16 September 2015 at 15:31, Thomas Koster <[email protected]> wrote: > Nathan, > > On 8 September 2015 at 15:58, Thomas Koster <[email protected]> wrote: > > F# appears to eliminate tail calls to self by program transformation > > where it is trivial to do so, but relies entirely on the CLR for > > optimizing tail calls in general. This would mean that the stability and > > reliability of programs written for the CLR in F# is uncertain, and that > > debug builds of F# programs are always unreliable. I would want much > > stronger guarantees about space complexity if I were to seriously > > consider F# as a programming language for paid work. > > > > So if anybody has used F# in the real world, what's the story? > > On 14 September 2015 at 18:06, Nathan Schultz <[email protected]> wrote: > > IIRC, as you said, for most tail-end recursion, you'll find that the IL > that > > F# generates is actually a simple loop with a mutable variable. In cases > > where there's continuations involved or more complex scenarios with > multiple > > recursive functions, F# will automatically provide the CLR with the .tail > > instruction. Work has gone into the CLR to better support tail end > > recursion, and there have been lots of fixes in recent versions (e.g. > going > > back a couple of years, there used to be scenarios where the JIT would > > ignore the flag, but have been fixed). > > > > I've never run into an issue myself, although infrequently I have heard > of > > corner-cases that still pose issues (e.g. > > > http://blogs.msdn.com/b/dotnet/archive/2015/07/28/ryujit-bug-advisory-in-the-net-framework-4-6.aspx > ). > > However, I've also heard it said that when it comes to tail-end > recursion F# > > is in a better place with the CLR than Scala is with the JVM. And both > are > > used in production even in financial institutions. > > > > Given that I (rarely) still run into other bugs in the .Net framework > with > > C#, I don't see this as anything different; testing (including on > different > > platforms) is a necessary part of application development, and with F# > it's > > no different. > > Thanks for your response. > > I readily believe that the JVM is a worse place for functional languages > than the CLR. But both seem to share the same weakness when it comes to > implementing functional languages: they both support only one evaluation > strategy, namely the stack-based, strict, call-by-value evaluation > strategy of the curly brace langauges (and their predecessors). The > opcodes needed to implement other strategies efficiently are missing. > > I am starting to see that I may have over-estimated the number of ways > space leaks caused by tail calls can creep into an F# program. But since > F# uses a strict evaluation order where tail call elimination is > absolutely necessary to avoid excessive space usage, the discretionary > nature of the ".tail" opcode prefix still makes me uneasy and I would > rather not have to write tests to verify the correctness of the F# > compiler, let alone the JIT compiler. > > So for now, for me, F# remains just an intellectual curiosity. > > -- > Thomas Koster >
