Continuation passing

Posted: June 3, 2009 in c#, ProS

While working on version 0.3 of ProS I had the following requirement:

When given a list of statements that all return a value of IProcessor (That interface defines a method called Process) call each processors process method in turn and pass the result of the execution to the next processor in the list if and only if the result is null. At the same time the sequence of calls needs to be wrapped in a new IProcessor object so that the entire sequence can be part of another sequence.

After trying a few different approaches I ended up with using continuation passing. But what is that?

given two methods:

public int GetRandomInt()

{

return new Random().GetNext();

}

public void DoSomethingWithAnInt(int i)

{

Console.WriteLine(i.ToString());

}

a main could look like this:

public int main()

{

var i = GetRandomInt();

DoSomethingWithAnInt(i);

}

if we wanted to turn that into continuation passing we would have to change the first method and make it something like

public void GetRandomInt(Action<int> doSomethingWithAnInt)

{

var i = new Random().GetNext();

doSomeThingWithAnInt(i);

}

and main would then simply be

public int main()

{

GetRandomInt(DoSomethingWithAnInt);

}

This is actually more common than what you might think at first. Think of any Async call in .NET you’ll probably remember that one of the arguments is an AsynCallback. That call back is the continuation of the Async call. So for implementing asyncromeous behaviour the continuation passing style is very straight forward, simply pass what you want executed when the first call completes.

I need to represent a tree where each node is a decision point. E.g I might need to represent the code structure

if(a())

{

DoA();

}

else if (b())

{

DoB();

}

else

{

throw new InvalioperationException(“No sensible default action”);

}

however a() and b() is not known compile time and the number of if’s is not known either.

I ended up with a class called ContinuationProcessor that looks similiar to this:

public class ContinuationProcessor<T> : Irpocessor<T>

{

public ContinuationProcessor(ContinuationProcessor<T> continuation, IProcessor<T> processor,Func<object[],bool> condition)

{

//initialize the private fields

}

//This method is defined in IProcessor

public T Process(T obj, params object[] arguments)

{

T processedObj = null;

if(condition((new object[]{processedObj}).Concat(arguments)))

{

processedObj = processor.Process(obj,arguments);

}

if(continuation != null)

{

processedObj =  continuation.Process(processedObj,arguments);

}

return processedObj;

}

}

So it ends up not being true continuation passing since I end up returning a value, but it does make it possible to represent an arbitrary number of decision points together with the code that should be executed in case the associated decision is taken.

It’s a lot of fun writing code that represent code, but it gives me a headache trying to debug it…

Advertisements
Comments
  1. Now that’s -crazy dude-…. just crazy =)

    And I guess it took some time to end up with the working solution. All insanity takes time.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s