<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Encoding monadic computations in C# using iterators</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Tomas Petricek</string-name>
          <email>tomas@tomasp.net</email>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>Charles University in Prague, Faculty of Mathematics and Physics</institution>
        </aff>
      </contrib-group>
      <fpage>61</fpage>
      <lpage>69</lpage>
      <abstract>
        <p>Many programming problems can be easily solved if we express them as computations with some non-standard aspect. This is a very important problem, because today we're struggling for example to e±ciently program multi-core processors and to write asynchronous code. Unfortunately main-stream languages such as Java or C# don't support any direct way for encoding unrestricted nonstandard computations. In languages like Haskell and F#, this can be done using monads with syntactic extensions they provide and it has been successfully applied to a wide range of real-world problems. In this paper, we present a general way for encoding monadic computations in the C# 2.0 language with a convenient syntax using an existing language feature called iterators. This gives us a way to use well-known non-standard computations enabling easy asynchronous programming or for example the use of software transactional memory in plain C#. Moreover, it also opens monads in general to a wider audience which can help in the search for other useful and previously unknown kinds of computations.</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>-</title>
      <p>
        ming mechanism based on shared memory, which
avoids the need for explicit locking [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ].
      </p>
      <p>
        The motivation for this article is that we want to
be able to use the techniques just described in a
mainstream and widely used C# language. The main
contributions of this paper are following:
² As far as we're aware, we show for the ¯rst time
that monadic computations can be encoded in C#
in a syntactically convenient way without placing
any restrictions on the C# statements that can
be used inside the computation. This can be done
purely as a library without changing the language
using widely adopted C# 2.0 features (Section 3).
² We use the presented technique to implement a
library that makes it easier to write scalable
multithreaded applications that perform long running
I/O operations. We demonstrate it using several
case study examples (Section 4).
² Finally, we describe a method for systematical
encoding of arbitrary monadic computation in C#
(Section 5). This technique can be used for
implementing other useful computations such as
software transactional memory and others.
In functional programming languages such as Haskell
and F#, monadic computations are used to solve wide
range of problems. In Haskell [
        <xref ref-type="bibr" rid="ref5">5</xref>
        ], they are frequently There are several related projects, mostly
conused to deal with state or I/O, which is otherwise di±- cerned with asynchronous programming (Section 6),
cult in a purely functional language. F# uses monadic but our aim is wider and focuses on monadic
computacomputations to add non-standard aspects such as tions in general. However, asynchronous computations
asynchronous evaluation, laziness or implicit error can nicely demonstrate the problem.
handling to an existing piece of code written in F#. In
this article, we'll prefer the F# point of view, meaning 1.1 Asynchronous computations in C# today
that we want to be able to adjust C# code to execute
di®erently, using additional aspects provided by the Since we're using asynchronous computations as the
monadic computation. primary real-world motivation for this paper, we
      </p>
      <p>
        The primary motivation for this work is that should ¯rst clarify what problem we want to solve is.
monadic computations are very powerful technique for Let's start by looking at naive synchronous code that
dealing with many modern computing challenges downloads the ¯rst kilobyte of web site content:
caused by the rise of multi-core processors and dis- 1: var req = HttpWebRequest.Create(url);
tributed web based applications. The standard F# li- 2: var rsp = req.GetResponse();
brary uses monadic computations to implement asyn- 3: var strm = rsp.GetResponseStream();
chronous work°ows [
        <xref ref-type="bibr" rid="ref16">16</xref>
        ] which make it easy to write 4: var read = strm.Read(buffer, 0, 1024);
communication with the web and other I/O operations
in the natural sequential style, but without blocking On lines 2 and 4 we're performing I/O operations
threads while waiting. In Haskell, monadic compu- that can take a long time, but that aren't CPU
tations are used for example to implement software bounded. When running the operation, the executing
transactional memory, which is a concurrent program- thread will be blocked, but it cannot perform any other
1: var req = HttpWebRequest.Create(url);
2: req.BeginGetResponse(a1 =&gt; {
3: var rsp = req.EndGetResponse(a1);
4: var strm = rsp.GetResponseStream();
5: strm.BeginRead(buffer, 0, 1024, a2 =&gt; {
6: int read = strm.EndRead(a2);
7: // ...
8: }, null);
9: }, null);
1: let downloadUrl(url:string) = async {
2: let req = HttpWebRequest.Create(url)
3: let! rsp = req.AsyncGetResponse()
4: let strm = rsp.GetResponseStream()
5: let buffer = Array.zeroCreate(8192)
6: let state = ref 1
7: while !state &gt; 0 do
8: let! read = strm.AsyncRead(buffer,0, 8192)
9: Console.WriteLine("got {0}b", read);
10: state := read }
2
      </p>
    </sec>
    <sec id="sec-2">
      <title>Background</title>
      <p>In this context \asynchronous" means that the
program invokes start of the operation, registers a
callback, transfers the control to the system and releases This function downloads the entire content of
the current thread, so that it can perform other work. a web page in a loop. Although it doesn't use the data
In the snippet above, we're starting two operations in any way and only reports the progress, it nicely
on lines 2 and 5 and we're using the C# 3.0 lambda demonstrates the principle. Its body is an async block,
function notation \=&gt;" to specify the callback func- which speci¯es that the function doesn't actually run
tion that will be eventually invoked. the code, but instead returns a value representing
com</p>
      <p>The code above is far less readable than the ¯rst putation that can be executed later.
synchronous version, but that's not the only prob- In the places where the original C# code executed
lem. To download the whole page, we'd need to call asynchronous operations, we're now using the let!
the BeginRead method in a loop until we fetched the Keyword (lines 3 and 8), which represents monadic
whole page, but that's ridiculously di±cult, because value binding. This means that instead of simply
aswe can't use any higher level constructs such as the signing value to a symbol, the computation invokes
while loop when writing code using nested callbacks. Bind operation that is provided by the async value
For every simple problem, the programmer has to ex- (called computation builder) giving it the rest of the
plicitly write a state machine using mutable state. code wrapped inside a function as an argument. The</p>
      <p>It is worth pointing out that using asynchronous Bind member speci¯es non-standard behavior of the
model does not in principle increase the CPU par- operation. In this case the behavior is that the
operaallelism in the application, but it still signi¯cantly tion is executed asynchronously.
improves the performance and makes the application The computation builder (in this case async) also
more scalable because it considerably reduces the de¯nes the meaning of other primitive constructs such
number of (expensive) threads the application creates. as the while loop or returning the result from a
function. These primitive operations are exposed as
standard methods with well-de¯ned type signatures:
work in the meantime. If we wanted to run hundreds computations that is already de¯ned in F# libraries.
of downloads in parallel, we could create hundreds This feature hasn't been described in the literature
of threads, but that introduces signi¯cant overheads before, so we quickly review it here.
(such as allocation of kernel objects and thread stack) When we wrap code inside an async block, the
and also increases context switching. The right way to compiler automatically uses continuation passing style
solve the problem on the .NET platform is to use the for specially marked operations. Moreover, we can use
Asynchronous Programming Model (APM): all standard language constructs inside the block
including for example the while loop:
To write non-blocking asynchronous code, we can use
continuation passing style where the next piece of code
to execute after an operation completes is given as
a function as the last argument to the operation. In
the snippet above we've written the code in this style
explicitly, but as we've seen this isn't a satisfying
solution.</p>
      <sec id="sec-2-1">
        <title>The ¯rst two functions are standard operations</title>
        <p>
          that de¯ne the abstract monadic type as ¯rst
described in [
          <xref ref-type="bibr" rid="ref18">18</xref>
          ]. These operations are also called bind
2.1 F# asynchronous work°ows and unit. The Bind member takes an existing
computation and a function that speci¯es how to produce
In F#, we can use asynchronous work°ows, which subsequent computation when the ¯rst one completes
is one particularly useful implementation of monadic and composes these into a single one. The Return
Bind : Async&lt;'a&gt; * ('a -&gt; Async&lt;'b&gt;) -&gt;
        </p>
        <p>Async&lt;'b&gt;
Return : 'a -&gt; Async&lt;'a&gt;
While : (unti -&gt; bool) * Async&lt;unit&gt; -&gt;</p>
        <p>Async&lt;unit&gt;
2.2</p>
        <sec id="sec-2-1-1">
          <title>C# Iterators</title>
          <p>member builds a computation that returns the given to the console, so the program above shows the
\genvalue. The additional While member takes a predicate erating" message directly followed by \got" for
numand a computation and returns result that executes bers 0 and 1. There are two key aspects of iterators
the computation repeatedly while the predicate holds. that are important for this paper:</p>
          <p>
            When compiling code that uses computation
expressions, the F# compiler syntactically transforms
the code into code composed from the calls to these
primitive operations. The translated version of the
previous example can be found in the online
supplementary material for the article [
            <xref ref-type="bibr" rid="ref12">12</xref>
            ].
² The iterator body can contain usual control
structures such as loops or exception handlers and the
compiler automatically turns them into a state
machine.
² The state machine can be executed only to a
certain point (explicitly speci¯ed by the user using
yield return), then paused and later resumed
again by invoking the MoveNext method again.
          </p>
          <p>
            One of the non-standard computations that is very
often used in practice is a computation that generates In many ways this resembles the continuation
passa sequence of values instead of yielding just a single ing style from functional languages, which is
essenresult. This aspect is directly implemented by C# it- tial for monadic computations and F# asynchronous
erators [
            <xref ref-type="bibr" rid="ref2">2</xref>
            ], but without any aim to be more generally work°ows.
useful. In this article, we show that it can be used in
a more general fashion. However, we start by brie°y
introducing iterators. The following example uses it- 3 Monadic computations in C#
erators to generate a sequence of all integers:
1: IEnumerator&lt;int&gt; GetNumbers() {
2: int num = 0;
3: while (true) {
4: Console.WriteLine("generating {0}", num);
5: yield return num++;
6: }
7: }
          </p>
          <p>The code looks just like ordinary method
with the exception that it uses the yield return
keyword to generate elements a sequence. The while
loop may look like an in¯nite loop, but due to the
way iterators work, the code is actually perfectly valid
and useful. The compiler translates the code into a
state machine that generates the elements of the se- 3.1
quence lazily one by one. The returned object of type
IEnumerator&lt;int&gt; can be used in the following way:</p>
        </sec>
      </sec>
      <sec id="sec-2-2">
        <title>Now that we've introduced asynchronous work°ows</title>
        <p>in F# (as an example of monadic computations) and
C# iterators, we can ask ourselves the question
whether iterators could be used for encoding other
non-standard computations then code that generates
a sequence.</p>
        <p>The key idea of this article is that it is indeed
possible to do that and that we can write standard C#
library to support any monadic computation. In this
section, we'll brie°y introduce how the library looks
using the simplest possible example and in section 5
we'll in detail explain how the encoding works.</p>
        <sec id="sec-2-2-1">
          <title>Using option computations</title>
          <p>1: var en = GetNumbers();
2: en.MoveNext();
3: Console.WriteLine("got {0}", en.Current);
4: en.MoveNext();
5: Console.WriteLine("got {0}", en.Current);</p>
        </sec>
      </sec>
      <sec id="sec-2-3">
        <title>Code that is composed from simple computations</title>
        <p>The call to the GetNumbers method (line 1) re- that return this type can return None value at any
turns an object that represents the state machine gen- point, which bypasses the entire rest of the
computaerated by the compiler. The variables used inside the tion. In practice this is useful for example when
permethod are transformed into a local state of that ob- forming series of data lookup that may not contain the
ject. Each call to the MoveNext method (lines 2 and 4) value we're looking for. The usual way for writing the
runs one step of the state machine until it reaches the code would check whether the returned value is None
next yield return statement (line 5 in the earlier
snippet) updating the state of the state machine. This also 1 In Haskell, this type is called Maybe and the
correspondexecutes all side-e®ects of the iterator such as printing ing computation is known as Maybe monad.</p>
      </sec>
      <sec id="sec-2-4">
        <title>As the ¯rst example, we'll use computations that pro</title>
        <p>duce value of type Option&lt;'a&gt; 1, which can either
contain no value or a value of type 'a. The type can
be declared using F#/ML notation like this:
type Option&lt;'a&gt; = Some of 'a | None
AsStep : Option&lt;'a&gt; -&gt; OptionStep&lt;'a&gt;
OptionResult.Create : 'a -&gt; OptionResult&lt;'a&gt;
after performing every single step of the computation,
which signi¯cantly complicates the code 2.</p>
        <p>To show how the code looks when we apply our
encoding of the option computation using iterators,
we'll use method of the following signature:</p>
      </sec>
      <sec id="sec-2-5">
        <title>The ¯rst method creates an object that corre</title>
        <p>sponds to the monadic bind operation. It takes the
option value and composes it with the computation that
ParseInt : string -&gt; Option&lt;int&gt; follows the yield return call. The second method
builds a helper that represents monadic unit
opera</p>
        <p>The method returns Some(n) when the parameter tion. That means that the computation should end
is a valid number and otherwise it returns None. Now returning the speci¯ed value as the result.
we can write code that reads a string, tries to parse it
and returns 10 times the number if it succeeds. The
result of the computation will again be the option type. 3.2 Executing option calculation
1: IEnumerator&lt;IOption&gt; ReadInt() { When we write code in the style described in the
previ2: Console.Write("Enter a number: "); ous section, methods like ReadInt only return a state
3: var optNum = ParseInt(Console.ReadLine()); machine that generates a sequence of helper objects
4: var m = optNum.AsStep(); representing bind and unit. This alone wouldn't be at
5: yield return m; all useful, because we want to execute the
computa6: Console.WriteLine("Got a valid number!"); tion and get a value of the monadic type (in this case
7: var res = m.Value * 10; Option&lt;'a&gt;) as the result. How to do this in terms of
8: yield return OptionResult.Create(res); standard monadic operations is described in section 5,
9: } but from the end user perspective, this simply means</p>
        <p>The code reads a string from the console and calls invoking the Apply method:
the ParseInt method to get optNum value, which has Option&lt;int&gt; v = ReadInt().Apply&lt;int&gt;();
a type Option&lt;int&gt; (line 3). Next, we need to per- Console.WriteLine(v);
form non-standard value binding to access the value
and to continue running the rest of the computation This is a simple piece of standard C# code that
only when the value is present. Otherwise the method runs the state machine returned by the ReadInt
can return None as the overall result straight ahead. method. Apply&lt;'a&gt; is an extension method 4 de¯ned</p>
        <p>To perform the value binding, we use the AsStep for the IEnumerator&lt;IOption&gt; type. Its type
signamethod that generates a helper object (line 4) and ture is:
then return this object using yield return (line 5).</p>
        <p>This creates a \hole" in the code, because the rest of Apply : IEnumerable&lt;IOption&gt; -&gt; Option&lt;'a&gt;
the code may or may not be executed, depending on
whether the MoveNext method of the returned state The type parameter (in the case above int)
specimachine is called again or not. When optNum contains ¯es what the expected return type of the computation
a value, the rest of the code will be called and we can is, because this unfortunately cannot be safely tracked
access the value using the Value property (line 7)3. in the type system. Running the code with di®erent</p>
        <p>Finally, the method calculates the result (line 7) inputs gives the following console output:
and returns it. To return from a non-standard compu- Enter a number: 42 Enter a number: $%?!
tation written using our encoding, we create another Got a valid number! None
helper object, this time using OptionResult.Create Some(420)
method. These helper objects are processed when
executing the method. Strictly speaking, Apply doesn't necessarily have</p>
        <p>
          To summarize, there are two helper objects. Both to execute the code, because its behavior depends on
of them implement the IOption interface, which the monadic type. The Option&lt;'a&gt; type represents
means that they can both be generated using yield re- a value, so the computation that produces it isn't
deturn. The methods that create these two objects have layed. On the other hand the Async&lt;'a&gt; type, which
the following signatures: represents asynchronous computations is delayed
meaning that the Apply method will only build a
com2 We could as well use exceptions, but it is generally ac- putation from the C# compiler generated state
macepted that using exceptions for control °ow is a wrong chine.
practice. In this case, the missing value is an expected
option, so we're not handling exceptional condition. 4 Extension methods are new feature in C# 3.0. They
3 The F# code corresponding to these two lines is: let! are standard static methods that can be accessed using
value = optNum dot-notation as if they were instance methods [
          <xref ref-type="bibr" rid="ref1">1</xref>
          ].
        </p>
        <p>The encoding of non-standard computations 4
wouldn't be practically useful if it didn't allow us to
compose code from primitive functions and as we'll see
in the next section, this is indeed possible.</p>
        <p>As discussed in the introduction, writing non-blocking
code in C# is painful even when we use latest C#
features such as lambda expression. In fact, we haven't
even implemented a simple loop, because that would
3.3 Composing option computations make the code too lengthy. We've seen that monadic
computations provide an excellent solution 5 and we've
seen that these can be encoded in C# using iterators.</p>
        <p>When encoding monadic operations, we're working As next, we'll explore one larger example that
folwith two di®erent types. The methods we write using lows the same encoding of monadic computations as
the iterator syntax return IEnumerator&lt;IOption&gt;, the one in the previous section, but uses a di®erent
but the actual monadic type is Option&lt;'a&gt;. monad to write asynchronous code that doesn't block
When writing code that is divided into multi- the tread when performing long-running I/O. The
folple methods, we need to invoke method return- lowing method reads the entire content of a stream
ing IEnumerator&lt;IOption&gt; from another method in a bu®ered way (using 1kb bu®er) performing each
written using iterators. The following example uses read asynchronously.
the ReadInt method from the previous page to read
two integer values (already multiplied by 10) and add 1: IEnumerator&lt;IAsync&gt; ReadToEndAsync(Stream s)
them. {</p>
        <p>Case study: asynchronous C#</p>
      </sec>
      <sec id="sec-2-6">
        <title>When the method needs to read an integer, it calls</title>
        <p>the ReadInt to build a C# state machine. To make 14:
the result useable, it converts it into a value of type 15: }
Option&lt;int&gt; (using the Apply method) and ¯nally
uses the AsStep method to get a helper object that The code uses standard while loop which would be
can be used to bind the value using yield return. previous impossible. Inside the body of the loop, the</p>
        <p>We could of course provide a method composed method creates an asynchronous operation that reads
from Apply and AsStep to make the syntax more con- 1kb of data from the stream into the speci¯ed bu®er
venient, but this paper is focused on explaining the (line 6) and runs the operation by yielding it as a value
principles, so we write this composition explicitly. from the iterator (line 7). The operation is then
exe</p>
        <p>The previous example also nicely demonstrates the cuted by the system and when it completes the iterator
non-standard behavior of the computation. When it is resumed. It stores the bytes to a temporary storage
calls the RadInt method for the second time (line 4) and continues looping until the input stream is fully
it does that after using non-standard value binding processed. Finally, the method reads the data using
(using yield return on line 3). This means that the StreamReader to get a string value and returns this
user will be asked for the second number only if the value using AsyncResult.Create method (line 14).
¯rst input was a valid number. Otherwise the result of The encoding of asynchronous computations is
esthe overall computation will immediately be None. sentially the same as the encoding of computations</p>
        <p>Calculating with options nicely demonstrates the with option values. The only di®erence is that the
principles of writing non- standard computations. We method now generates a sequence of IAsync values.
can use non-standard bindings to mark places where Also, the AsStep method now returns an object of type
the code can abandon the rest of the code if it already AsyncStep&lt;'a&gt; and similarly, the helper object used
knows the overall result. Even though this is already 5 To justify this, we can say that asynchronous work°ows
useful, we can make even stronger point to support are one of the important features that contributed to
the idea by looking at asynchronous computations. the recent success of the F# language.
for returning the result is now AsyncResult&lt;'a&gt;. write code that is generic over the monadic type
Thanks to the systematic encoding described in sec- (e.g. Option&lt;'a&gt; and Async&lt;'a&gt;). As a result, we
tion 5, it is very easy to use another non-standard need to de¯ne a new set of helper objects for each type
computation once the user understands one example. of computation. To make this task easier, we provide</p>
        <p>The method implemented in the previous listing two base classes that encapsulate functionality that
is very useful and surprisingly, it isn't available in can be reused. The code that we need to write is the
the standard .NET libraries. We'll use it to asynchro- same for every computation, so writing it is a
straightnously download the entire web page. However, we forward task that could be even performed by a very
¯rst need to asynchronously get the HTTP response, simple code-generator tool.
so we'll write the code as another asynchro- In this section, we'll look at the code that needs
nous method using iterator syntax. In section 3.3, to be written to support calculations working with
we've seen how to compose option computations and option values that we were using in section 3. The
since the principle is the same, it isn't surprising that code uses only two computation-speci¯c operations.
composing asynchonous computations is also straight- Indeed, these are the two operations bind and unit
forward: that are used to de¯ne monadic computations in
functional programming (\O" is a shortcut for \Option"):
1: var stream = resp.Value.GetResponseStream();
2: var html = ReadToEndAsync(stream).
3: Execute&lt;string&gt;().AsStep();
4: yield return html;
5: Console.WriteLine(html.Value);
Bind : O&lt;'a&gt; -&gt; ('a -&gt; O&lt;'b&gt;) -&gt; O&lt;'b&gt;
Return : 'a -&gt; O&lt;'a&gt;</p>
      </sec>
      <sec id="sec-2-7">
        <title>The bind operation uses the function provided as</title>
        <p>the second parameter to calculate the result when the</p>
        <p>
          The listing assumes that we already have a re- ¯rst parameter contains a value. The unit operation
sponse object (resp). So far we haven't seen how to ac- wraps an ordinary value into an option value. The
tually start the download, because asynchronous com- implementation of these operations is described
elseputations are delayed, meaning that we're just con- where, so we won't discuss it in detail. You can for
exstructing a function that can be executed later. This ample refer to [
          <xref ref-type="bibr" rid="ref11">11</xref>
          ]. We'll just assume that we already
makes it possible to compose large number of compu- have OptionM type with the two operations exposed
tations and spawn them in parallel. The runtime then as static methods.
uses only a few threads, which makes it very e±cient
and scalable. You can ¯nd full example that shows
how to start the download in the online supplemen- 5.1 De¯ning iterator helpers
tary material for the article [
          <xref ref-type="bibr" rid="ref12">12</xref>
          ] As a ¯rst thing, we'll implement helper objects that
        </p>
        <p>Implementing the functionality we presented are returned from the iterator. We've seen that we
in this section asynchronously using the usual style need two helper objects - one that corresponds to bind
would be far more complicated. For example, to imple- and one that corresponds to unit. These two objects
ment the ReadToEndAsync method we need two times share common interface (called IOption in case of
opmore lines of very dense C# code. However, the code tion computations) so that we can generate a single
also becomes hard to read because it cannot use many sequence containing both of them. Let's start by
lookhigh-level language features (e.g. while loop), so it ing at the interface type:
would in addition also require a decent amount of
comments6.
interface IOption {</p>
        <p>Option&lt;R&gt; BindStep&lt;R&gt;(Func&lt;Option&lt;R&gt;&gt; k);
5</p>
      </sec>
    </sec>
    <sec id="sec-3">
      <title>Encoding arbitrary monads</title>
      <p>}</p>
      <sec id="sec-3-1">
        <title>The BindStep method is invoked by the extension</title>
        <p>As we've seen in the previous two sections, writing that executes the non-standard computation (we'll
dismonadic computations in C# using iterators requires cuss it later in section 5.2). The parameter k speci¯es
several helper objects and methods. In this section, a continuation, that is, a function that can be
exewe'll look how these helpers can be de¯ned. cuted to run the rest of the iterator. The continuation</p>
        <p>
          Unfortunately, C# doesn't support higher-kinded doesn't take any parameters and returns an option
polymorphism, which is used when de¯ning monads in value generated by the rest of the computation. The
Haskell and is available in some object-oriented lan- implementation of the helper objects that implement
guage such as Scala [
          <xref ref-type="bibr" rid="ref10">10</xref>
          ]. This means that we can't the interface looks like this:
6 The source code implementing the same functionality in
the usual style can be found in [
          <xref ref-type="bibr" rid="ref12">12</xref>
          ]
the monadic computation. The purpose of the
iterator isn't to create a sequence of values, so we need to
execute it in some special way. The following example
shows an extension method Apply that turns the
iterator into a monadic value. In case of options the type
of the value is Option&lt;'a&gt; but note that the code
will be exactly the same for all computation types.
static class OptionExtensions {
public static Option&lt;R&gt; Apply&lt;R&gt;
        </p>
        <p>(this IEnumerator&lt;IOption&gt; en) {
if (!en.MoveNext())
throw new InvalidOperationException</p>
        <p>("Enumerator ended without a result!");
return en.Current.BindStep&lt;R&gt;(() =&gt;</p>
        <p>en.Apply&lt;R&gt;());
}
}
class OptionStep&lt;T&gt; : MonadStep&lt;T&gt;, IOption {
internal Option&lt;T&gt; Input { get; set; }
public Option&lt;R&gt; BindStep&lt;R&gt;(Func&lt;Option&lt;R&gt;&gt; k)
{
return OptionM.Bind(Input,
MakeContinuation(k));
}
}
class OptionResult&lt;T&gt; : MonadReturn&lt;T&gt;, IOption
{
internal OptionResult(T value) : base(value)
{ }
public Option&lt;R&gt; BindStep&lt;R&gt; (Func&lt;Option&lt;R&gt;&gt;
k) {
return OptionM.Return(GetResult&lt;R&gt;());
}
}</p>
        <p>The OptionStep&lt;'a&gt; type has a property named
Input that's used to store the option value from which
the step was constructed using the AsStep method. The method starts by invoking the MoveNext
When the BindStep method is executed the object method of the generated iterator to move the
iterauses the monadic bind operation and gives it the input tor to the next occurrence of the yield return
stateas the ¯rst argument. The second argument is more in- ment. If the return value is false, the iterator ended
teresting. It should be a function that takes the actual without returning any result, which is invalid, so the
value extracted from the input option value as an ar- method throws an exception.
gument and returns a new option value. The extracted If the iterator performs the step, we can access the
value can be used to calculate the result, but there is next generated helper object using the en.Current
no way to pass a value as an argument back to the it- property. The code simply invokes BindStep of the
erator in the middle of its evaluation, which is why the helper and gives it a function that recursively calls the
function given as the parameter to BindStep method Apply method on the same iterator as the argument.
doesn't take any parameters. Note that when the helper is OptionResult&lt;'a&gt;, the</p>
        <p>As we've seen in the examples, the continuation isn't used, so the recursion terminates.
OptionStep&lt;'a&gt; helper exposes this value as the It is worth noting that for monadic computations
Value property. This property is inherited from the with zero operation we can also write a variant of
MonadStep&lt;'a&gt; type. The MakeContinuation which the Apply method that doesn't require the iterator
we use to build a parameter for monadic bind oper- to complete by returning a result. In that case, we'd
ation is also inherited and it simply stores the input modify the method to return a value constructed by
obtained from bind into Value, so that it can be used the monadic zero operation instead of throwing an
exin the iterator and then runs the parameter-less con- ception in the case when the iterator ends.
tinuation k. Finally, there are also some problems with using</p>
        <p>
          The OptionResult&lt;'a&gt; type is a bit simpler. It possibly deeply nested recursive calls in a language
has a constructor that creates the object with some that doesn't guarantee the use of tail-recursion. We
value as the result. Inside the BindStep method, it can overcome this problem by using some technique for
uses the monadic unit operation and gives it that value tail-call elimination. Schinz [
          <xref ref-type="bibr" rid="ref15">15</xref>
          ] gives a good overview
as the parameter. This cannot be done in a statically in the context of the Scala language. Perhaps the
eastype-checked way, so we use the inherited GetResult iest option to implement is to use a trampoline [
          <xref ref-type="bibr" rid="ref17">17</xref>
          ].
method that performs dynamic type conversion.
Finally, the OptionResult.Create and AsStep meth- 5.3 Translation semantics
ods are just simple wrappers that construct these two
objects in the syntactically most pleasant way.
        </p>
      </sec>
      <sec id="sec-3-2">
        <title>To formalize the translation in a more detail, we've</title>
        <p>
          also developed a translation semantics for the library.
5.2 Implementing iterator evaluation We ¯rst de¯ne an abstract language extension for C#
that adds monadic compuations as a language feature
Once we have an iterator written using the helpers to C# in a way similar to F#. Then we show that any
described in the previous section, we need some way code written in the extended C# can be translated
for executing it using the non-standard behavior of to the standard C# 2.0 by using the iterator encoding
presented in this article. The grammar of the language
extension as well as the semantic rules are available in
the online supplementary material [
          <xref ref-type="bibr" rid="ref12">12</xref>
          ].
6
        </p>
      </sec>
    </sec>
    <sec id="sec-4">
      <title>Related work and conclusions</title>
      <p>There is actually one more way for writing
some monadic computations in C# using the recently
added query syntax. The syntax is very limited, but
may be suitable for some computations. We'll brie°y
review this option and then discuss other relevant
related work and conclusions of this paper.
6.1</p>
      <sec id="sec-4-1">
        <title>LINQ queries</title>
        <p>many functional features to C++, including monads,
which means it should be possible to use it for
reimplementing some examples from this paper.</p>
        <p>
          There are also several libraries that use C#
iterators for encoding asynchronous computations. CCR [
          <xref ref-type="bibr" rid="ref7">7</xref>
          ]
is a more sophisticated library that combines join
patterns with concurrent and asynchronous
programming, which makes it more powerful than our
encoding. On the other hand it is somewhat harder to use for
simple scenarios such as those presented in this paper.
        </p>
        <p>
          Richter's library [
          <xref ref-type="bibr" rid="ref13">13</xref>
          ] is also focused primarily on
asynchronous execution. It uses yield return primitive
slightly di®erently - to specify the number of
operations that should be completed before continuing the
execution of the iterator. The user can then pop the
results from a stack.
        </p>
        <p>
          As many people already noted [
          <xref ref-type="bibr" rid="ref8">8</xref>
          ], the LINQ query
syntax available in C# 3.0 is also based on the idea
of monad and can be used more broadly than just 7 Conclusions
for encoding computations that work with lists. The
following example shows how we could write the com- In this paper, we have presented a way for encoding
putation with option values using LINQ syntax: monadic computations in the C# language using
iter1: Option&lt;int&gt; opt = ators. We've demonstrated the encoding with two
ex2: from n in ReadInt() amples - computations that work with option values
3: from m in ReadInt() and computations that allow writing of non-blocking
4: let res = m + n asynchronous code.
5: select res; The asynchronous library we presented is useful
in practice and would alone be an interesting result.
        </p>
        <p>However, we described a general mechanism that can
be useful for other computations as well. We believe
that using it to implement for example a prototype
of software transactional memory support for C# can
bring many other interesting results.</p>
        <p>
          The implementation of library that allows this kind
of syntax is relatively easy and is described for
example in [
          <xref ref-type="bibr" rid="ref11">11</xref>
          ]. This syntax is very restricted. In it allows
non-standard value bindings corresponding to the bind
operation using the from keyword (lines 2 and 3),
standard value bindings using the let construct (line 4) and
returning of the result using select keyword (line 5).
        </p>
        <p>However, there are no high-level imperative constructs
such as loops which were essential for the
asynchronous example in section 4. With some care, it is
possible to de¯ne several mutually recursive queries, but
that still makes it hard to write complex computations
such as the one in section 4.</p>
        <p>
          On the other hand, query syntax is suitable for
some monadic computations where we're using only
a limited language. Parser combinators as described
for example in [
          <xref ref-type="bibr" rid="ref6">6</xref>
          ] can be de¯ned using the query
syntax [
          <xref ref-type="bibr" rid="ref4">4</xref>
          ]. In general, C# queries are a bit closer to
writing monads using the Haskell's list comprehension
notation, while using iterators as described in this article
is closer to the Haskell's do-notation.
6.2
        </p>
      </sec>
      <sec id="sec-4-2">
        <title>Related work</title>
        <sec id="sec-4-2-1">
          <title>The principle of using a main-stream language for encoding constructs from the research world has been used with many interesting features including for example Joins [14]. FC++ [8] is a library that brings</title>
        </sec>
      </sec>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          1.
          <string-name>
            <given-names>G.M.</given-names>
            <surname>Bierman</surname>
          </string-name>
          , E. Meijer,
          <string-name>
            <surname>M.</surname>
          </string-name>
          <article-title>Torgersen: Lost in translation: formalizing proposed extensions to C#</article-title>
          .
          <source>In Proceedings of OOPSLA</source>
          <year>2007</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          2.
          <string-name>
            <given-names>ECMA</given-names>
            <surname>International</surname>
          </string-name>
          .: C#
          <article-title>Language Speci¯cation.</article-title>
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          3.
          <string-name>
            <given-names>T.</given-names>
            <surname>Harris</surname>
          </string-name>
          ,
          <string-name>
            <given-names>S.</given-names>
            <surname>Marlow</surname>
          </string-name>
          ,
          <string-name>
            <given-names>S.</given-names>
            <surname>Peyton-Jones</surname>
          </string-name>
          ,
          <string-name>
            <surname>M.</surname>
          </string-name>
          <article-title>Herlihy: Composable memory transactions</article-title>
          .
          <source>In Proceedings of PPoPP</source>
          <year>2005</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          4. L. Hoban:
          <article-title>Monadic parser combinators using C# 3.0</article-title>
          . Retrieved May
          <year>2009</year>
          , from http://blogs.msdn.com/lukeh/archive/2007/08/19/ monadic-parser
          <article-title>-combinators-using-c-3-0</article-title>
          .aspx
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          5.
          <string-name>
            <given-names>P.</given-names>
            <surname>Hudak</surname>
          </string-name>
          ,
          <string-name>
            <given-names>P.</given-names>
            <surname>Wadler</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Brian</surname>
          </string-name>
          ,
          <string-name>
            <given-names>B.J.</given-names>
            <surname>Fairbairn</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J.</given-names>
            <surname>Fasel</surname>
          </string-name>
          ,
          <string-name>
            <given-names>K.</given-names>
            <surname>Hammond</surname>
          </string-name>
          et al.:
          <article-title>Report on the programming language Haskell: A non-strict, purely functional language</article-title>
          .
          <source>ACM SIGPLAN Notices.</source>
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          6.
          <string-name>
            <given-names>G.</given-names>
            <surname>Hutton</surname>
          </string-name>
          , E. Meijer:
          <article-title>Monadic parser combinators</article-title>
          .
          <source>Technical Report</source>
          . Department of Computer Science, University of Nottingham.
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          7.
          <string-name>
            <given-names>G.</given-names>
            <surname>Chrysanthakopoulos</surname>
          </string-name>
          ,
          <string-name>
            <surname>S. Singh:</surname>
          </string-name>
          <article-title>An asynchronous messaging library for C#</article-title>
          .
          <source>In proceedings of SCOOL Workshop</source>
          , OOPSLA,
          <year>2005</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          8.
          <string-name>
            <given-names>B.</given-names>
            <surname>McNamara</surname>
          </string-name>
          ,
          <string-name>
            <surname>Y.</surname>
          </string-name>
          <article-title>Smaragdakis: Syntax sugar for FC++: lambda, in¯x, monads, and more</article-title>
          .
          <source>In Proceedings of DPCOOL</source>
          <year>2003</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          9. E. Meijer:
          <article-title>There is no impedance mismatch (Language integrated query in Visual Basic 9)</article-title>
          .
          <source>In Dynamic Languages Symposium</source>
          , Companion to OOPSLA
          <year>2006</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          10.
          <string-name>
            <given-names>A.</given-names>
            <surname>Moors</surname>
          </string-name>
          ,
          <string-name>
            <given-names>F.</given-names>
            <surname>Piessens</surname>
          </string-name>
          ,
          <string-name>
            <surname>M.</surname>
          </string-name>
          <article-title>Odersky: Generics of a higher kind</article-title>
          .
          <source>In Proceedings of OOPSLA</source>
          <year>2008</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          11.
          <string-name>
            <given-names>T.</given-names>
            <surname>Petricek</surname>
          </string-name>
          ,
          <string-name>
            <surname>J.</surname>
          </string-name>
          <article-title>Skeet: Functional Programming for the Real World</article-title>
          . Manning,
          <year>2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          12. T. Petricek:
          <article-title>Encoding monadic computations using iterators in C# 2.0 (Supplementary material)</article-title>
          . Available at http://tomasp.net/academic/ monads-iterators.aspx
        </mixed-citation>
      </ref>
      <ref id="ref13">
        <mixed-citation>
          13. J. Richter:
          <article-title>Power threading library</article-title>
          .
          <source>Retrieved May</source>
          <year>2009</year>
          , from http://www.wintellect.com/ PowerThreading.aspx
        </mixed-citation>
      </ref>
      <ref id="ref14">
        <mixed-citation>
          14.
          <string-name>
            <surname>C</surname>
          </string-name>
          .V.
          <article-title>Russo: The Joins concurrency library</article-title>
          .
          <source>In Proceedings of PADL</source>
          <year>2007</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref15">
        <mixed-citation>
          15.
          <string-name>
            <surname>M. Schinz</surname>
            ,
            <given-names>M.</given-names>
          </string-name>
          <article-title>Odersky: Tail call elimination on the Java Virtual Machine</article-title>
          .
          <source>In Proceedings of BABEL 2001 Workshop on Multi-Language Infrastructure and Interoperability.</source>
        </mixed-citation>
      </ref>
      <ref id="ref16">
        <mixed-citation>
          16.
          <string-name>
            <given-names>D.</given-names>
            <surname>Syme</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Granicz</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Cisternino: Expert</surname>
          </string-name>
          <string-name>
            <surname>F</surname>
          </string-name>
          #,
          <year>Apress</year>
          ,
          <year>2007</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref17">
        <mixed-citation>
          17.
          <string-name>
            <given-names>D.</given-names>
            <surname>Tarditi</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Acharya</surname>
          </string-name>
          ,
          <string-name>
            <surname>P.</surname>
          </string-name>
          <article-title>Lee: No assembly required: Compiling standard ML to C</article-title>
          . School of Computer Science, Carnegie Mellon University.
        </mixed-citation>
      </ref>
      <ref id="ref18">
        <mixed-citation>
          18. P. Wadler:
          <article-title>Comprehending monads</article-title>
          .
          <source>In Proceedings of ACM Symposium on Lisp and Functional Programming</source>
          ,
          <year>1990</year>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>