Friday, September 22, 2006

Recursive Nested Functions in C#

I was wondering today if it were possible to create nested functions. Procedures seem pretty straightforward: name an anonymous delegate and then invoke it later in the code using the name. But what about functions? Well, functions can be manage by declaring the delegate type first (shown in the example). What about recursive nested functions? Well, the name assigned to the delegate doesn't exist until after the anonymous delegate block. So, to recurs use reflection and pull the method right of the stack frame.


using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Diagnostics;
namespace NestedFunction
{
class Program
{
delegate long FactorialDelegate(long n);
static void Main(string[] args)
{
//recursive nested function - calculates Factorial(n)
FactorialDelegate Factorial = delegate(long n)
{
MethodBase method =
new StackTrace().GetFrame(0).GetMethod();
return n > 1 ? n * (long)method.Invoke(null,
new object[]{ n - 1 }) : n;
};
Console.WriteLine(Factorial(5));
Console.ReadLine();
}
}
}

In the code listing I declared a function delegate. In the main procedure an instance of that delegate type is declared and assign to an anonymous delegate. The Anonymous method pulls itself of the stackframe and can recurs. Later (or anywhere) in the function the delegate instance can be used like any other function.

Probably slow. Definitely heinous looking, but it does mean C# could support nested functions directly and you could use them now if you wanted to.

Friday, September 08, 2006

The Missing LINQ

The jury is still out for me. I think LINQ (or Language INtegrated Query) is a cool technology. The problem for me is that it looks like SQL and SQL aint pretty. Ultimately LINQ will prove to be powerful, but I wonder if the SQL-like syntax will make code more or less abstruse. Throw in some lambda equations and the code looks messy (to me anyway).

Here is a DLINQ example, followed by a sample using lambda equation.

private static void DatabaseQuery()
{
Northwind db = new Northwind(
@"C:\Program Files\LINQ review\Data\Northwnd.mdf");
var match = from c in db.Customers
where c.Country == "USA" && c.ContactName.Contains("Yoshi")
orderby c.ContactName descending
select c;

foreach(var o in match)
Console.WriteLine("> {0} / {1} / {2}", o.CompanyName, o.ContactName, o.Country);
Console.ReadLine();
}



delegate T Func(T t);
private static void Lambda()
{
Func funcDel = delegate(int x){ return x+x; };
Func lambda = x => x+x;
Console.WriteLine(funcDel(5));
Console.WriteLine(lambda(5));
}


In both cases the code looks like it needs a lot of comments to describe what is happening, and things that need a lot of comments by implication aren't clear. Unclear is generally considered bad. (Did I mention SQL queries are ugly?!)

Well, it looks like LINQ, XLINQ, and DLINQ are here to stay, so let me see if I can get some mielage out of it.

This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]