Category Archives: Monads

Give your async delegate type the right name

The BCL has well-known delegate types representing synchronous invocation signatures: Action<> and Func<>. But what about asynchronous methods? An asynchronous method with no return value translates to Func<Task>. That looks kind of strange because usually Func means a function with a return value but actually all we are getting is a Promise that the operation will complete without a result. A task amplifies (or let’s say wraps) a result (or void) but instead of having an asynchronous construct which handles the result directly, Task and result are treated as one unit as part of a synchronous call.

The following table shows the synchronous types and how you have to specialize them to get asynchronous versions:

WhatSynchronousAsynchronous w. BCL
no argument and no resultActionFunc<Task>
one argument and no resultAction<T>Func<T, Task>
no argument but resultFunc<TResult>Func<Task<TResult>>
one argument and resultFunc<T,TResult>Func<T,Task<TResult>>

This leads to code like this:

// Sample asynchronous method which takes
// no parameter and returns no result (Func<Task>)
public async Task DoAsync()
{
await Task.Delay(42); // pretend we do something
}

// Method calling asynchronous lambda
public async Task CallAsync(Func<Task> func)
{
await func();
}

public async Task Orchestrate()
{
Func<Task> func = () => DoAsync();
await CallAsync(func);
}

As said at the beginning, I think especially for people who are not so firm in asynchronous programming it becomes confusing that Func<T> actually represents a function with no parameters and no return value. Even for advanced programmers this is something they constantly have to have in their mind when reading code. Therefore, I believe generic asynchronous delegate types are missing in the BCL and should be part of every project with asynchronous code. The following definitions tackle this problem:

Proposed asynchronous typesDefinition of asynchronous types
AsyncActiondelegate Task AsyncAction();
AsyncAction<T>delegate Task AsyncAction<in T>(T arg);
AsyncFunc<TResult>delegate Task<TResult> AsyncFunc<out TResult>();
AsyncFunc<T,TResult>delegate Task<TResult> AsyncFunc<in T, out TResult>(T arg);
// Sample asynchronous method which takes no
// parameter and returns no result (AsyncAction)
public async Task DoAsync()
{
await Task.Delay(42); // pretend we do something
}

// Method calling asynchronous lambda
public async Task CallAsync(AsyncAction action)
{
await action();
}

public async Task Orchestrate()
{
AsyncAction action = () => DoAsync();
await CallAsync(action);
}

Beside being easier to read this also supports better recognition of what is a command and what is a query in your code (referring to CQRS in Wiki orĀ Fowler )

Flattr this!

Amplify C#

Recently, while following the coursera course on reactive programming and especially Erik Meijer’s introduction to Scala I’ve got interested in some monad types Scala has to offer. What monads are, has already extensively been described on the web. For example Wes Dyer or Eric Lippert offer excellent explanations.
In the following posts I want to have a closer look at Scala’s Option and how it could be ported to C#. The amplification (a term coined in Wes Dyer’s blog post) behind Option is nothing new to C# developers: For a certain type it either holds some or none value of that type. A functionality which is already available with the class Nullable of T in C#. Unfortunately Nullable of T is restricted to value types – It cannot be used with reference types. Of course people have written their own Nullable implementations which allow T to be a reference type as well but my goal is to learn about the inner mechanics of such a Nullable/Maybe/Option type rather than re-using an existing one.

Flattr this!