Functional Magic
In the shower this morning, as the haze of sleep was clearing, I was thinking about delegates in C#. (Yes, I’m a complete and total geek. As if there was any debate on that issue. :) An interesting thought occurred to me, though, so I naturally had to throw together a proof of concept. It’s another one of those ideas whose usefulness is debatable for most cases, but is interesting nonetheless.
A functor, which is a term from functional programming, is an function represented as an object. In C#, functors are implemented as delegates. C# 2.0 introduced some language features like implicit delegate creation and invocation, which give the appearance of first-class functions. This significantly narrows the gap between actual method declarations and delegates.
A class is essentially a collection of methods along with some data that defines its state. Consider this class definition:
1: public class Formatter
2: {
3: public string Format(string message)
4: {
5: return message.ToLower();
6: }
7: }
Very straightforward. To use this Formatter class, you could do something like this:
1: public static class Program
2: {
3: public static void Main()
4: {
5: Formatter fmt = new Formatter();
6:
7: // Outputs "my message!"
8: Console.WriteLine(fmt.Format("My Message!"));
9: }
10: }
Nothing groundbreaking there either. But what if, instead of actually defining your method directly, you did this instead?
1: public class Formatter
2: {
3: public Functions.Format Format = delegate(string message)
4: {
5: return message.ToLower();
6: }
7:
8: public class Functions
9: {
10: public delegate string Format(string message);
11: }
12: }
Take a close look at that snippet. Rather than declaring a Format method on the Formatter type, we’ve given it a public Format field. The Format field is of type Formatter.Functions.Format, which is a delegate defined in an inner class called Functions. (The inner type just keeps the outer Formatter type clean of any delegate definitions.) Then, using anonymous method syntax, we’ve assigned the Format field a value, which is the same as our previous implementation of the Format method.
What we’ve essentially done is separated the signature of the method from its implementation. You can still use the Formatter just like before:
1: public static class Program
2: {
3: public static void Main()
4: {
5: Formatter fmt = new Formatter();
6:
7: // This triggers the Format delegate, resulting in the same
8: // output of "my message!"
9: Console.WriteLine(fmt.Format("My Message!"));
10: }
11: }
But, since the implementation is separate from the declaration, we can do fun stuff like:
1: public class Program
2: {
3: public static void Main()
4: {
5: Formatter fmt = new Formatter();
6:
7: // Change the implementation of Format.
8: fmt.Format = delegate(string s) { return s.ToUpper(); };
9:
10: // This outputs "MY MESSAGE!"
11: Console.WriteLine(fmt.Format("My Message!"));
12: }
13: }
You could even get more creative:
1: public class Program
2: {
3: public static void Main()
4: {
5: Formatter fmt = new Formatter();
6:
7: // Save a copy of the original implementation (ToLower)
8: Formatter.Functions.Format func = fmt.Format;
9:
10: // Wrap the function with another implementation.
11: fmt.Format = delegate(string s) { return "The message is [" + func(s) + "]"; };
12:
13: // This will output "The message is [my message!]"
14: Console.WriteLine(fmt.Format("My Message!"));
15: }
16: }
This technique is used pretty commonly in dynamic languages like Ruby, but it can still be applied to more static languages like C#. Arguably, it would be nice if there was support for this in the language (say through the virtual keyword, or a new one like externalizable), but I have a feeling it would be misused pretty quickly. :)










Magic so early in the morning, ugh!
OK, so it’s not *that* early. I needed something to get my brain juiced and this did the trick. :)
Ideas like this make me wonder if we’re not moving more and more toward a super-massive language which can be both static and dynamic at the same time, depending on how you use it. Which naturally makes me wonder if such wicked-coolness would result in a productivity boon as developers realize the power… or will it become overly abused and come to represent all that is wrong with the world.
Discuss amongst yourselves.
Yeah, so maybe that’s a bit extreme… but I think those are true questions and concerns that we will need to face at some point. But for now, let us bask in the hotness that is Functional Magic.
I think the traditional OO alternative to this idea would be using composition with interfaces.
The difference in use would be that instead of doing fmt.Format(“My Message!”) you’d do something like fmt.Format.With(“My Message!”) (yes I read your EDSL post ;) )