Reading Mads Torgersen old blog post on Recursive Lambda Expressions, I decided it was time for me to seriously play with his code and try out the fixed point generator to create recursive lambda expressions (together with the fact that I was sick and felt bored).

Taking lessons from that blog post, I created a reusable fixed point generator which we can use for anything that uses recursion. Here’s the code, simply.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public static Func<T, T> Fix<T>(Func<Func<T, T>, Func<T, T>> F) { return x => F(Fix<T>(F))(x); } public static Func<T, T, T> Fix<T>(Func<Func<T, T, T>, Func<T, T, T>> F) { return (x, n) => F(Fix<T>(F))(x, n); } public static Func<T1, T2, T1> Fix<T1, T2>(Func<Func<T1, T2, T1>, Func<T1, T2, T1>> F) { return (x, n) => F(Fix<T1, T2>(F))(x, n); } public static Func<T, T, T, T> Fix<T>(Func<Func<T, T, T, T>, Func<T, T, T, T>> F) { return (x, n, k) => F(Fix<T>(F))(x, n, k); } |

Static Fix methods are the actual Fixed Point Generator as described in Mads’ blog. This simplifies the code and makes it reusable. The method at lines 11-14 shows how 2 different input can be used. I will be using this method for the sine and cosine lambda expressions I’ve written.

1 2 3 |
Func<double, double> factorial = Fix<double>(fac => x => x == 0 ? 1 : x * fac(x - 1)); Func<double, int, double> sine = Fix<double, int>(sin => (x, n) => n == 0 ? x : sin(x, n - 1) + Math.Pow(-1, n) * Math.Pow(x, 2 * n + 1) / factorial(2 * n + 1)); Func<double, int, double> cosine = Fix<double, int>(cos => (x, n) => n == 0 ? 1 : cos(x, n - 1) + Math.Pow(-1, n) * Math.Pow(x, 2 * n) / factorial(2 * n)); |

The factorial lambda expression is the same as in Mads’ blog. I’ve created both sine and cosine lambda expressions learning from how the fixed point generator works. I have to keep factorial as double instead of int because it’ll make the precision wrong.

I used the Taylor Series in order to generate the sine and cosine function. x is the angle in radians, and n is the number of recursion to do (i.e. the more recursion, the more precision).

The basic recursion is as follows:

So that’s that! Plug in your lambda expression into the Fix static method and you’re done, you’ve got recursion.

Further testing out whether if it actually works, here’s a simple testing code:

1 2 3 4 5 6 7 8 9 10 11 |
for (int i = 0; i < 20; i++) { Console.WriteLine(factorial(i)); } Console.WriteLine(sine(Math.PI / 4, 10)); Console.WriteLine(Math.Sin(Math.PI / 4)); Console.WriteLine(cosine(Math.PI / 3, 10)); Console.WriteLine(Math.Cos(Math.PI / 3)); Console.ReadKey(); |

Here, what I do is I check my sine and cosine output with the actual Math.Sin and Math.Cos methods from the framework. It looks like it works well with n = 10 or higher, achieving the same precision as the framework.

That’s that. I will play around with more of this, and create more methods out of this.

I tried generalizing the method itself to make it look better and easier to read, but the limits of Generics in C# stopped me from doing anything further. Here’s what I tried to do, but failed of course.

1 2 3 4 5 |
// I need a constraint operator- to make this work, but Generics does not support this public static Func<T, T> Factorial<T>() where T : struct, IEquatable<T>, operator- { return Fix<T>(fac => x => x.Equals(0) ? 1 : x * fac(x - 1)); } |

If that was successful, then the code would have been reduced to simply like this.

1 |
Factorial(5) |

Doesn’t that look better? If only, but there must be come other way to do this.