Continuation Passing Style

My tour of functional programming idioms in C# 3.0 continues with some continuation tests. These two tests are equivalent:

[Test]
public void ExplicitReturnStyle()
{
    Assert.That(someObject.Identity("foo"), Is.EqualTo("foo"));
}

[Test]
public void ContinuationPassingStyle()
{
    someObject.Identity("foo", s => Assert.That(s, Is.EqualTo("foo")));
}

Given these two overrides of Identity:

public T Identity<T>(T foo)
{
    return foo;
}

public void Identity<T>(T foo, Action<T> f)
{
    f(foo);
}

In the Continuation Passing Style Identity doesn't return a value. Return'ing is simulated by passing what comes after the function (the continuation) as a function object. In many functional languages continuations are so central to how things work that this is how you return values (and those languages are optimized for doing this). For those of you like me who grew up with the imperative children of pascal, this may be somewhat mind-bending at first. It will also likely have you saying "why would anyone do this?"

Rather than steal his entire article, go see Wes Dyer's article on the subject (where I got the identity example) for more about why one might do this outside of a language (like Scheme or Erlang) where this idiom is apparently the norm.

For even more details (including why this isn't quite CPS) see this by Don Box.

BTW, my answer to "Why do this?" is: "When it is the best way to solve the problem at hand." That I don't know when that will be yet, doesn't really concern me. I don't always learn things with a specific application in mind. Sometimes, I learn things so that when a problem arises, I have a lot of different tools in my toolbox. In other words, I am learning it because its interesting, a bunch of people smarter and more knowledgeable than me have found uses for it, and I might someday too (and I definitely won't if I don't know about it!)

Perhaps the best reason to learn this stuff is because Microsoft has put some sharp tools in the C# toolbox and I think its better to know how they work so that - even if I rarely ever take them out - I don't get cut on them while rummaging around in there.

UPDATE: For Wes's take on why it's important, see here (and really his whole series on the topic is worth the read!)

UPDATE2: If you want to take a deeper tour of these and many other functional concepts, this series of articles by Dustin Campbell goes far and wide if you follow all the links (and the links' links and so on...)