The Dictionary of Func
15 Jan

The Dictionary of Func

  Early in my programming career, I was chastised for using a case statement in a simple factory. "You should be using a dictionary" he told me. "It makes the code cleaner and prevents adding too much logic in the factory." Although I wasn't prepared to handle the architecture concepts he presented with the statement. I did understand the impact that it made on the look of the code, which was now considerably easier to read.

C#

// a simple case statement (9 lines of code)
switch (number)
{
    case 1:
        Console.WriteLine("the number is one");
        break;
    case 2:
        Console.WriteLine("the number is two");
        break;
        //...
}

// a simple dictionary selector (6 lines of code)
private static Dictionary<int, string> numbers = new Dictionary<int, string>()
{
    { 1, "the number is one"},
    { 2, "the number is two"},
};
Console.WriteLine(numbers[number]);

  When the idea of static dictionaries as a selection structure was first brought to my attention, it was only usable for simple expression trees. If the the logic in the tree deviated structurally you would have to re-factor, or go back to your switch statement. With the addition of functional delegates in .Net 3.5. the Dictionary of Func or Dictionary<TKey,Func<TParam,TResult>> was born.

C#

// a more complex case statement with arbitrary functionality
switch (number)
{
    case 1:
        Console.WriteLine("the number is one");
        results = CalculationsForOnlyNumberOne(number);     
        break;
    case 2:
        Console.WriteLine("the number is two");
        results = CalculationsForOnlyNumberTwo(number);
        break;
        //...
}

// The Dictionary of Func 
private static Dictionary<int, Func<int,Results>>> numbers = new Dictionary<int, Func<int,Results>>>()
{
    { 1,(number) => {
            Console.WriteLine("the number is one");
            return CalculationsForOnlyNumberOne(number);
        }   
    },
    { 2,(number) => {
            Console.WriteLine("the number is two");
            return CalculationsForOnlyNumberTwo(number);
        }   
    },
};
results = numbers[number](number);

  There is a catch. In C# specifically the switch statement allows you access the scope of the class that contains it, the dictionary of func requires the logic to be static. And while this may seem like a major drawback, I run into it very rarely, since most instances where you would use a switch, is to determine inputs for larger more stateful processes and not in the middle of them. This is not the case for more functional languages, like Scala or javascript.

Scala

val numbers : Map[int,(int)=>Result] = (
    1 -> (number) => {
        println("the number is one, and a local variable is: %s".format(myLocal))
        CalculationsForOnlyNumberOne(number)
    },
    2 -> (number) => {
        println("the number is two, and a local variable is: %s".format(myLocal))
        CalculationsForOnlyNumberTwo(number)
    },
)
results = numbers(number)(number)

Javascript

var numbers = { };
numbers[1] = function(number){
    console.log('the number is one, and a local variable is: ' + myLocal )
    return CalculationsForOnlyNumberOne(number);
}
numbers[2] = function(number){
    console.log('the number is two, and a local variable is: ' + myLocal )
    return CalculationsForOnlyNumberTwo(number);
}
results = numbers[number](number);

  I find the Dictionary of Func preferable to the switch statement in most cases. It is cleaner, more conciese, and a whole lot more fun to say.