Not just a function : Generating functions

Every now and then, you hit some problem that a programming language helps solve very cleanly. Here’s the problem.

You are writing a series of functions that return a bool depending on some condition (predicates). Something like

bool Foo(State t);

Let’s also assume that State is defined as

class State  { Color c; ... }

You have a set of colors, known at compile time, for which Foo should return true. How would you go about doing it?

You could pack the set of colors into an array and write Foo so that at runtime, it searches the color array and returns true if the color passed is in the array. Something like

bool Foo(State t) { return colors.IndexOf(t.Color) != -1; }

Assume that, for design reasons, it isn’t really possible to allow access to colors from within Foo. Then what?

Anonymous methods and closures, of course. How about writing a function, that returns a Foo that returns true only if the color matches. Whew, that sounds confusing, but the code looks pretty simple.

Foo GenerateFoo(Color color) { return delegate(Color passedColor) { return color == passedColor; } }

You can then call GenerateFoo(Color.Red) to get a Foo that will return true only if it is called with Color.Red, call GenerateFoo(Color.Orange) to get one that returns true only if called with Color.Orange and so on.

Foo redFoo = GenerateFoo(Color.Red);
Foo orangeFoo = GenerateFoo(Color.Orange);
Console.WriteLine(redFoo(Color.Red)); // prints true
Console.WriteLine(redFoo(Color.Yellow)); // prints false

Nifty, eh?

 

2 thoughts on “Not just a function : Generating functions”

  1. Yes, there is no looping at runtime – at the cost of constructing a delegate, creating an instance of the compiler generated type for holding the captured variable, and then actually evaluating the returned function. It’s probably worth the tradeoff if the generated function gets called a lot more times than the generator function – generate once, use many times.
    I don’t understand the relation between this and List/SomeClass[]? You could loop over the collection and generate one function for each element, if that’s what you mean.
    And there’s nothing that restricts it to compile time values, you could have something like

    string s = Console.ReadLine();
    Color c = (Color)Enum.Parse(typeof(Color), s);
    var foo = GenerateFoo(c);
    Console.WriteLine(foo(Color.Orange));

    Really cool :)

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>