On Tuesday 04 March 2008 16:52:35 Eric Lavigne wrote:
> > > I was under the impression that the tail-recursion optimization could
> > > not be applied to a function that might throw an exception because
> > > debugging information would be lost (tail-recursion changes the stack
> > > trace). If I am wrong about this, I would love to hear it.
> > What you're referring to only applies to functions that handle
> > exceptions using "try" blocks. Specifically, exception handlers must be
> > pushed onto the stack so they obviate any tail-like calls between the
> > "try" and the "with".
> > Raising exceptions is fine: it does not undermine tail calls.
> So if I place a "try ... with" at the top of my application, as in the
> following pseudo-application, tail-recursion is turned off for the
> entire application?
No. Only that call is a non-tail call. This does not have a global effect.
> Ouch. My previous (mis)understanding of the
> situation was much more pleasant. Now the performance of my function
> depends on the context in which the function is used.
> run_my_application ()
> Stack_overflow -> print_endline "Functional programming and error
> handling don't mix as well as I thought."
That one call to "run_my_application" is not a tail call because it lies
between the "try" and "with".
let rec f() =
with _ -> ()
and g() =
The call to "g()" is not a tail call because it appears inside a "try" block
but the call to "f()" is a tail call.
Dr Jon D Harrop, Flying Frog Consultancy Ltd.