Click here to Skip to main content
15,881,588 members
Articles / Web Development / ASP.NET

Implementing Continuations in a Generic Way - The Usage of the Option Type in C# - Make Code More Clear

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
23 Aug 2011CPOL4 min read 23.2K   273   13   3
Continuations in C# - Make code more clear
This article show how to make code more clear, easier to write and more extensible in a generic way. Use of Option type in C# in combination of Func delegates

Introduction

Problem to solve: If you look at a lot of code in C#, the code must be read from top to bottom, following all the If, Else, Try and other branches to really understand what is happening. Furthermore, a lot of this code is basically technically, such as checking on null-values. I wondered if you could write code that reads from left to right, and is in principle not-technical. It reads like a series of operations that makes sense as such. A ‘similar’ concept is known in F# as pipelining. In F#, it looks like:

Let squared =
  Numbers
 |> List.filter isOdd
 |> List map square;;

The object Numbers are pipelined through the functions that follows. In C#, I wanted to do something like this:

C#
[SomeObject].AndThen(isValid)
  . AndThen(Save)
  . AndThenIfElse(Do_this_If_ThisIsTrue, Do_this_IfOtherwise)

Etc. In this case, the SomeObject is passed to function IsValid and then to Save and then to the Do_this_If_ThisIsTrue, which function can return 'false', in which case SomeObject is passed to Do_this_ifOtherWise. The beauty of this chaining is that we can add any number of AndThen, AndThenIfElse as we want.

You could do this years ago using delegates. Delegates are eventually not generic. Now we can use these, but we also want to handle Error handling and null-alike code. Tomas Petricek and John Skeet Real-World Functional Programming comes with the solution. The secret is in essentially two things: the Option type and the using of essentially only one fixed interface: (func of Option of T, Option of T), meaning you pass in a function that receives an Option and returns one. This interface can be chained or pipelined as much as you want.

The Option Type is a well-known Type in F#. An Option can be None or Some. Some wraps an actual business object. Continuations is the concept in which you pass the result of a function to another function.

What if you combine those two concepts? There is a lot of theory involved, but I won't bother you with it. If you wrap an object in an Option and then use Continuation, you can keep on chaining as shown in the above AndThen code. The Option object hides the actual type of the object inside it.

Inside the Option can be anything. Using the Option-concept, we can let behave a strict typed language in a generic way.

For continuation, you can use Lambdas, but then the typing won't let you implement these in a generic way.

This article is about implementing Continuation in a generic way.

The Option type is an abstract class with two concrete implementations: None and Some. None ends the chaining, Some encapsulates the [SomeObject]. A function must first get the encapsulated object, do some processing on it and return either a None or a Some with the encapsulated object. The Option Some and None classes are generic!

To this Option type, I added some functions, such as the above AndThenIfElse. If you look at the parameters, you see that you pass the following two parameters: Func of Option of T, Option of T tryFirst, Func of Option of T, Option of T tryNext, meaning you pass in two functions.

I added:

  1. AndThen (continuation). If the previous function returns a Some, then continue with the following function
  2. AndThenCheck. You pass in as the first parameter a function that takes an Option and returns a Boolean. If this Boolean is true, the second parameter is executed, which is a continuation. If not true, return None.
  3. AndThenCaseCheck. You pass in a list of AndThenCheck. If a check returns true, the accompanying continuation is executed. If none of the checks returns true, a None is returned. In the accompanying example, I use lambdas to compose this list. Funcs can be replaced by lambdas and in this case, I thought it was a good idea.
  4. AndThenIfElse. You pass in two functions. If the first return None, the second continuation is executed.

The other interesting thing to note is that the above pipeline of continuations is not executed until a call to Exec(). The reason to do this, is because Exceptions are handled in the Exec() call only, and the continuations stop with the first None returns. The pipeline is in fact an arraylist of MultiCastDelgates that can be serialized. The option/Continuation concept can be used in other scenarios as well such as postponing execution by saving until it’s triggered in time.

I added a concrete example of how to use this in the real world. The code is not doing much, but gives you a good idea how you can use it. Looking at the code below (ClientController), you see the real benefit:

C#
someClientData.AndThen(isValid)
    .AndThen(ClientBusiness.Save)
    .AndThenIfElse(ClientBusiness.CheckOnDustin, ClientBusiness.CheckOnNotDustin)
    .AndThenCheck(ClientBusiness.ANameLengthCheck, ClientBusiness.GetLastOneInLocality)
    .AndThenCaseCheck(ClientBusiness.SomeCaseListOnProfession())
    .Exec();

Does the code read from left to right and does it read as a series of chained operations? Does it 'hide' technical handlings in favor of business handlings? What do you think? Let me know.

History

  • 23rd August, 2011: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Netherlands Netherlands
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
SuggestionVery interesting subject Pin
Mike Klimentiev31-Aug-11 12:25
Mike Klimentiev31-Aug-11 12:25 
QuestionWhat do you mean by 'Delegates are eventually not generic'? Pin
Rob Philpott23-Aug-11 6:38
Rob Philpott23-Aug-11 6:38 
AnswerRe: What do you mean by 'Delegates are eventually not generic'? Pin
KP Lee30-Aug-11 16:46
KP Lee30-Aug-11 16:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.