Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optimizing tail-calls in C#

I've got a deeply recursive function that should in theory work well even with large inputs. The problem is at the time of writing I forgot that C# doesn't do tail-call optimization very well, if at all, so I get StackOverflowExceptions for any complex-enough input. The basic structure of the method is in two large methods, each calling the other.

public object Simplify(object param) {
    if (IsSimple(param))
        return param;
    else
        return Expand(param);
}

private object Expand(object param) {
    return Simplify(ProcessExpansion(param));
}

Both IsSimple and ProcessExpansion have a relatively fixed stack depth - the only problem is the recursion between Simplify and Expand. How would you go about reducing the stack depth here?

I was thinking of returning delegates that would calculate the result, but that seems like overkill - there must be a simpler way. This is my thought of a solution (it isn't very polished because I keep thinking I must be doing something horribly wrong here):

public object Simplify(object param) {
    object result = () => SimplifyInternal(param);
    while (result is Func<object>)
        result = ((Func<object>)result)();
    return result;
}

private object SimplifyInternal(object param) {
    if (IsSimple(param))
        return param;
    else
        return Expand(param);
}

private object Expand(object param) {
    return () => SimplifyInternal(ProcessExpansion(param));
}

So my two questions are:

  1. What is it that feels horribly wrong with this solution?
  2. Can you think of a better one?
like image 641
configurator Avatar asked May 20 '26 06:05

configurator


1 Answers

Isn't this just

while(!IsSimple(param))
    param = ProcessExpansion(param);
return param;

?

like image 127
Brian Avatar answered May 21 '26 18:05

Brian



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!