At the very end of that F# team blog post Nathan linked they say:

"Most of these restrictions have been lifted in .NET 4.0
<http://blogs.msdn.com/b/clrcodegeneration/archive/2009/05/11/tail-call-improvements-in-net-framework-4.aspx>
."

... and if you read the linked article ..

"For CLR 4 the fact that the x64 JIT would sometimes not honor the “tail.”
prefix prevented functional languages like F# from being viable.  So we
worked to improve the x64 JIT so that it could honor the “tail.” prefix all
of the time and help make F# a success.  Except where explicitly called
out, x86 and IA64 remain unchanged between CLR 2 and CLR 4, and the
remainder of this document refers solely to the x64 JIT.  Also this is
specific to CLR 4, all other versions of the runtime or JIT (including
service packs, QFEs, etc.) might change this in any number of ways."
On 17 Sep 2015 2:47 pm, "Thomas Koster" <[email protected]> wrote:

> 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).
>
> On 17 September 2015 at 14:54, Nathan Schultz <[email protected]> wrote:
> > 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).
>
> This is interesting because Petricek contradicts ECMA-335 here. (I
> checked both 5th ed and 6th ed.) I'm not asking that you defend his
> claims; I'm just making a comment here :)
>
> I accept prima facie that the F# compiler guarantees that it will emit
> the ".tail" opcode prefix before all function calls in tail position,
> but Petricek makes a stronger claim that I cannot find any supporting
> evidence for. He says, "the compiler generates a tail-call instruction
> that tells the JIT that it *must* use a tail call". However, the CLR
> does not actually have to honour the ".tail" opcode prefix in all
> situations as he claims.
>
> Secondly, he gives an example that is exactly one of the situations
> where ECMA-335 says an implementation is permitted to ignore the ".tail"
> opcode: a virtual method call. ECMA-335 justifies this relaxation of the
> rules because CAS usually need a proper stack frame to work correctly.
>
> It is possible that Petricek knows some secrets about Microsoft's JIT
> compiler that we don't. If he does, he should back up his claims with
> them or I will have to go with what ECMA-335 says and assume that the
> JIT compiler will ignore all the ".tail" opcodes at any time that
> ECMA-335 says it is allowed to ignore them.
>
> I know this sounds pessimistic, and usually I don't care so much about
> code that I can fix myself, but when it comes to the compiler and the
> runtime, I expect strong guarantees. One of the first things my CS
> lecurer said long ago was that I should never rely on optimizations
> performed by the compiler for correct behaviour.
>
> --
> Thomas Koster
>

Reply via email to