<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Matthew Podwysocki's Blog : F#, Concurrency</title><link>http://weblogs.asp.net/podwysocki/archive/tags/F_2300_/Concurrency/default.aspx</link><description>Tags: F#, Concurrency</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><item><title>Pondering Axum + F#</title><link>http://weblogs.asp.net/podwysocki/archive/2009/09/25/pondering-axum-f.aspx</link><pubDate>Fri, 25 Sep 2009 20:39:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7216647</guid><dc:creator>podwysocki</dc:creator><author>podwysocki</author><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/podwysocki/rsscomments.aspx?PostID=7216647</wfw:commentRss><comments>http://weblogs.asp.net/podwysocki/archive/2009/09/25/pondering-axum-f.aspx#comments</comments><description>&lt;P&gt;It’s been a while since I’ve posted about &lt;A href="http://msdn.microsoft.com/en-us/devlabs/dd795202.aspx" mce_href="http://msdn.microsoft.com/en-us/devlabs/dd795202.aspx"&gt;Axum&lt;/A&gt; as I’ve been posting about other asynchronous and parallel programming models.&amp;nbsp; After two releases of the Axum standalone language and lots of good user feedback, it’s time to ponder what could be with Axum.&amp;nbsp; Overall, the goals of Axum to provide an agent-based concurrency oriented system is important as we consider the emerging hardware trends.&amp;nbsp; Many of these ideas would in fact benefit most languages, whether mainstream or not.&amp;nbsp; With all the success that it has had, there have also been some issues as well, which leads me to wonder, what else could we do here?&amp;nbsp; Let step through some of those issues today and see where we could go.&lt;/P&gt;
&lt;H2&gt;Should It Be Its Own Language?&lt;/H2&gt;
&lt;P&gt;One of the highlighted concerns was the need to have yet another language.&amp;nbsp; Creating and maintaining languages is a large effort, not to be undertaken lightly at any organization.&amp;nbsp; To base your language on C# while adding additional constructs was a great way to get started and create some buzz and buy-in, but it also brought its own set of problems.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;One problem is that it is an enormous effort to keep on par with the C# compiler and add these constructs on a continuing basis.&amp;nbsp; The Spec# project, also based upon C# realized that it wasn’t feasible to keep up with the rapid pace of the language and instead went as a language neutral approach.&amp;nbsp; Not only keeping up with the language, but to enforce many functional programming constructs that Axum embraces such as immutability and purity are harder to enforce given a language which is built upon object-oriented and imperative approaches, an approach which encourage the encapsulation and manipulation of state.&amp;nbsp; So, instead of creating a separate language, why not fold these constructs into an existing language instead?&lt;/P&gt;
&lt;H2&gt;The Case For F#&lt;/H2&gt;
&lt;P&gt;Given the impedance mismatch between the C# language and the overall goals of Axum for a safe, isolated, agent-based system that is great for concurrency, why not consider another language such as F#?&amp;nbsp; Now that F# is a first-class citizen within Visual Studio going forward, there can be a strong case made.&amp;nbsp; Given some of the features of F#, which we will discuss, could potentially be a happy marriage with Axum.&amp;nbsp; The F# language and its associated libraries have many of the constructs that are essential to an agent-based messaging system, including immutability (albeit shallow), encouraging side effect free programming, and library functions such as the mailbox processor messaging classes.&lt;/P&gt;
&lt;H2&gt;In Praise Of Immutability&lt;/H2&gt;
&lt;P&gt;In the world of concurrency we find that shared mutable state is evil.&amp;nbsp; Often we have to protect certain parts by using low level constructs such as locks, semaphores, mutexes.&amp;nbsp; Because of this, we find that most people tend to avoid concurrency programming as it tends to be too hard to get just right.&amp;nbsp; Instead, communication through message passing in languages such as Axum and Erlang, immutability is the standard.&amp;nbsp; This way, we can freely reference the values without any worry of whether they will change underneath us.&amp;nbsp; Providing first-class support for immutability goes a long way towards making safe concurrency programming easier for the masses.&amp;nbsp; With the F# language, we get that approach by default and with rich types such as records, discriminated unions, lists, tuples and more.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Of particular note, Discriminated Unions are quite useful in messaging systems to define the types of messages your system accepts.&amp;nbsp; For example, we could model our auction messages quite easily using discriminated unions to define which interactions are legal, such as the following code:&lt;/P&gt;
&lt;DIV style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id=scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:af8b6f4c-9ece-42ca-851b-71958ff2d310 class=wlWriterSmartContent&gt;&lt;PRE style="BACKGROUND-COLOR: #ffffff; OVERFLOW: auto"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; AuctionMessage &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
  &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;|&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; Offer of &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;*&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; MailboxProcessor&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;AuctionReply&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
  &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;|&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; Inquire of MailboxProcessor&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;AuctionReply&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;and&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;  AuctionReply &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
  &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;|&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; Status of &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;*&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; System.DateTime
  &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;|&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; BestOffer
  &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;|&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; BeatenOffer of &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
  &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;|&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; AuctionConcluded of 
      MailboxProcessor&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;AuctionReply&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;*&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; MailboxProcessor&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;AuctionReply&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
  &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;|&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; AuctionFailed
  &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;|&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; AuctionOver&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/DIV&gt;
&lt;P&gt;In this case, we have succinctly defined what messages can be processed.&amp;nbsp; Adding to this, Axum, through the use of data-flow networks and channel protocols could be a nice compliment to determine how these messages are processed.&amp;nbsp;&amp;nbsp; Where else could they match up nicely?&lt;/P&gt;
&lt;H2&gt;Built For Concurrency&lt;/H2&gt;
&lt;P&gt;To talk about a potential marriage between F# and Axum, we need to talk about the language and its libraries and how they support concurrency.&amp;nbsp; From first class events, to asynchronous workflows, to mailbox processors, F# has a wide array of asynchronous and parallel programming libraries available out of the box.&amp;nbsp; In particular, the asynchronous workflows and the mailbox processor could match well with the Axum programming model.&amp;nbsp; Interestingly, &lt;A href="http://blogs.msdn.com/lucabol/" mce_href="http://blogs.msdn.com/lucabol/"&gt;Luca Bolognese&lt;/A&gt; has built upon the mailbox processor for his &lt;A href="http://blogs.msdn.com/lucabol/archive/2009/09/18/lagent-an-agent-framework-in-f-part-ix-counting-words.aspx" mce_href="http://blogs.msdn.com/lucabol/archive/2009/09/18/lagent-an-agent-framework-in-f-part-ix-counting-words.aspx"&gt;LAgent framework&lt;/A&gt; to show some more interesting scenarios where agent based programming could work.&amp;nbsp; This includes such things as advanced error handling, hot swapping, implementing MapReduce and so on.&lt;/P&gt;
&lt;P&gt;With little effort, we can model such things as the standard ping-pong example using F# mailboxes:&lt;/P&gt;
&lt;DIV style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id=scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:a25322f1-22dd-4b5b-a3c1-660d19314ebb class=wlWriterSmartContent&gt;&lt;PRE style="BACKGROUND-COLOR: #ffffff; OVERFLOW: auto"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;let&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; (&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;lt;--&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;) (m:MailboxProcessor&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;_&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;) msg &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; m.Post(msg)
&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; PingMessage &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; Ping of MailboxProcessor&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;PongMessage&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;|&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; Stop
&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;and&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;  PongMessage &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; Pong

&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;let&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; ping iters (pong : MailboxProcessor&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;PingMessage&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;) &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
  &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; MailboxProcessor&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;PongMessage&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;fun&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; inbox &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;-&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; 
    pong &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;lt;--&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; Ping inbox
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;let&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;rec&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; loop pingsLeft &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; async { 
      &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;let&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;!&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; msg &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; inbox.Receive()
      &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;match&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; msg &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;with&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
      &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;|&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; Pong &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;-&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; 
          &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; pingsLeft &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;%&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;1000&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;0&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;then&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
            printfn &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Ping: pong&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
          &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; pingsLeft &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;0&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;then&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
            pong &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;lt;--&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; Ping inbox
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;!&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; loop(pingsLeft &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;-&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;1&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;)
          &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;else&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
            printfn &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Ping: stop&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
            pong &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;lt;--&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; Stop
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; () }
    loop (iters &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;-&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;1&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;))
            
&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;let&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; pong () &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
  &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; MailboxProcessor&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;PingMessage&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;fun&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; inbox &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;-&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; 
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;let&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;rec&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; loop pongCount &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; async { 
      &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;let&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;!&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; msg &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; inbox.Receive()
      &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;match&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; msg &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;with&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
      &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;|&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; Ping sender &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;-&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; 
          &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; pongCount &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;%&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;1000&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;0&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;then&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
            printfn &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Pong: ping %d&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; pongCount
          sender &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;&amp;lt;--&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; Pong
          &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;!&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; loop (pongCount &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;+&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;1&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;) 
      &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;|&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; Stop &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;-&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; printfn &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Pong: stop&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; () }
    loop &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;0&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;)

&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;let&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; ponger &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; pong()
&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;let&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; pinger &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; ping &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800080"&gt;100000&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; ponger
pinger.Start()
ponger.Start()&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/DIV&gt;
&lt;P&gt;And you’ll notice from all of this, there are no mutable values anywhere nor shared global state and all communication happens through message passing.&amp;nbsp; We have certain limitations here such as we cannot remote these calls, so all interaction happens inside the single application.&amp;nbsp; Not only that, but how do we enforce no shared state?&lt;/P&gt;
&lt;H2&gt;What Would It Look Like?&lt;/H2&gt;
&lt;P&gt;So, now that we looked at some of the reasons why F# and Axum might be a good marriage, what might it actually look like?&amp;nbsp; That’s a great question!&amp;nbsp; Some of the concepts from Axum could map perfectly to F# whereas some might need a little more coaxing.&amp;nbsp; Let’s go back to the basic building blocks of Axum.&amp;nbsp; They consist of the following:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Agents and domains &lt;/LI&gt;
&lt;LI&gt;Channels &lt;/LI&gt;
&lt;LI&gt;Schema &lt;/LI&gt;
&lt;LI&gt;Networks &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The first three items are concerned mostly with state isolation and the exchange of information between our isolated regions of our application, while the last item deals more with the how messages are passed.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The domain is the most basic isolation concept where all data is encapsulated and only constructors are exposed outside of the domain definition.&amp;nbsp; Agents are defined to run within the isolated space of a domain with each agent on a separate thread of control.&amp;nbsp; These agents are exposed to one another through passing messages back and forth via channels which define ports through which our data flows.&amp;nbsp; The data that passes between our domains can be defined in a schema, similar in nature of XML Schemas, to define structure and rules of our data.&amp;nbsp; Now to think about message passing, F# already has asynchronous behavior already built in to the mailbox processor, so we could take advantage here and build on top of it and our networks could guide us as to what order messages are passed.&lt;/P&gt;
&lt;P&gt;Let’s look at some possible code examples of what things might look like.&amp;nbsp; I’ll choose just a couple as they might work nicely out of the box.&amp;nbsp; Let’s first look at how we might define a port which accepts a given message.&amp;nbsp; &lt;/P&gt;
&lt;DIV style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id=scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:4214dc67-da06-41bb-bc66-72e129322987 class=wlWriterSmartContent&gt;&lt;PRE style="BACKGROUND-COLOR: #ffffff; OVERFLOW: auto"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; ProductInput &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; Multiply of &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;*&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;|&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; Done
&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; ProductOutput &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; Product of &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;|&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; AckDone&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/DIV&gt;
&lt;P&gt;This way, we could define what our payload type for both incoming and outgoing.&amp;nbsp; Another area would be to look how schemas might be done.&amp;nbsp; In our earlier example, we used simple data types such as integers, but what about more complex types?&amp;nbsp; Using F#, we could think of using records here to simulate the not only the data, but what is and is not required:&lt;/P&gt;
&lt;DIV style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; FLOAT: none; PADDING-TOP: 0px" id=scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:4cd19f3b-99df-4ff0-b64d-2c1cba34fcd5 class=wlWriterSmartContent&gt;&lt;PRE style="BACKGROUND-COLOR: #ffffff; OVERFLOW: auto"&gt;&lt;SPAN style="COLOR: #0000ff"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; PersonSchema &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; 
  { Name     : &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
    Employer : &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
    Age      : &lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;int&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; option }

&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;let&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; matt &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
  { Name &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Matthew Podwysocki&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
    Employer &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;Microsoft Corporation&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;
    Age &lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: #000000"&gt; None }&lt;/SPAN&gt;&lt;/PRE&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/DIV&gt;
&lt;P&gt;By marking the fields we require as standard fields and those which are optional as option types works out nicely.&amp;nbsp; Using F#, we’re able to have concise syntax with a language that is already defined and quite flexible.&lt;/P&gt;
&lt;H2&gt;Conclusion&lt;/H2&gt;
&lt;P&gt;As you can see from this post, a potential marriage between Axum and F# would certainly be a great fit.&amp;nbsp; Instead of focusing on Axum as a separate language, focusing the effort on top of an existing language which matches many of the design goals can bear a lot of fruit.&amp;nbsp; I believe Axum is important for the .NET programming stack, giving us more options on how to deal with concurrency and changing hardware architectures.&amp;nbsp; What do you think?&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7216647" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Axum/default.aspx">Axum</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Concurrency/default.aspx">Concurrency</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Functional+Programming/default.aspx">Functional Programming</category></item><item><title>F# – Async Running with Continuation Scissors</title><link>http://weblogs.asp.net/podwysocki/archive/2009/06/20/f-async-running-with-continuation-scissors.aspx</link><pubDate>Sat, 20 Jun 2009 06:09:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7131022</guid><dc:creator>podwysocki</dc:creator><author>podwysocki</author><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/podwysocki/rsscomments.aspx?PostID=7131022</wfw:commentRss><comments>http://weblogs.asp.net/podwysocki/archive/2009/06/20/f-async-running-with-continuation-scissors.aspx#comments</comments><description>&lt;p&gt;As you may have noticed, I’ve been covering a bit about concurrency on this blog lately, and for good reason.&amp;nbsp; Between Axum, Erlang, Scala and F#, there is a lot to explore with actor model concurrency, task based concurrency, data parallel applications and so on.&amp;nbsp; In the next couple of months, I have some talks coming up on concurrency and in particular with F#.&amp;nbsp; I’ve been covering a bit of that with F# and mailbox processing, but I wanted to step back a bit into the asynchronous workflows and hitting against a well known API.&amp;nbsp; &lt;/p&gt;

&lt;p&gt;In this case, let’s walk through a simple example of using the &lt;a href="http://apiwiki.twitter.com/Twitter-API-Documentation"&gt;Twitter HTTP API&lt;/a&gt; to get a user timeline using F# asynchronous workflows.&amp;nbsp; Best of all, I’ve done all of the above code without ever once opening up Visual Studio and instead using the power of a simple text editor and F# interactive, I’m able to be quite productive.&amp;nbsp; It certainly makes me rethink my utter dependence on certain tools…&lt;/p&gt;

&lt;h2&gt;Give me some tweets… eventually, when you get around to it&lt;/h2&gt;

&lt;p&gt;In order to get started, we need some helpers when dealing with LINQ to XML.&amp;nbsp; &lt;a href="http://codebetter.com/blogs/matthew.podwysocki/archive/2009/06/11/f-duck-typing-and-structural-typing.aspx"&gt;In a previous post&lt;/a&gt;, I talked about the need for such a thing due to the lack of implicit operator support in F#.&amp;nbsp; We can use the same operator that we had before such as the following:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:199c0565-d5a0-406e-a951-99c08a147a45" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;inline&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; implicit arg &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
    (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;^&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;a : (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;member&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; op_Implicit : &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;^&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;b &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;^&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;a) arg)

&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) : string &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; XName &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; implicit&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Alternatively, we could look at utilizing the XNamespace as well due to it also having an implicit operator to convert from a string.&amp;nbsp; This is helpful as it has a defined the op_Addition which allows us to add an XNamespace to a string to create an XName.&amp;nbsp; To take advantage we could add an additional operator to take care of this.&amp;nbsp; Below is a simple session of F# interactive to show how it might work:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:4de5fc91-a1c5-4ccf-8767-beb3c23053ff" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!?&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) : string &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; XNamespace &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; implicit;;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;val&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ( &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!?&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ) : (string &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; XNamespace)

&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;+&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!?&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;""&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;val&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; it : (string &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; XName) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;fun&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;:it@&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;205&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;

&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!?&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;""&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;+&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;foo&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;val&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; it : XName &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; foo {LocalName &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;foo&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;
                      Namespace &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ;
                      NamespaceName &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;""&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;}&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;If you’ll notice above, I curried the XNamespace implicit operator function and sure enough it recognizes it needs a string in order to produce an XName.&amp;nbsp; Now that we’ve defined our helpers, let’s start looking at how to get a user’s timeline in Twitter.&amp;nbsp; We’ll need to define a holder for our status data as well as the URL we will be using to post data.&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:3d95bf17-90e2-4de7-9105-5a4eb994d342" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;type&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; UserStatus &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; { UserName : string; ProfileImage : string; Status : string; StatusDate : DateTime }

&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; timelineUrl &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;http://twitter.com/statuses/friends_timeline.xml&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;We’re interested at this point just of the user name, their image file location, their status and the date of the tweet.&amp;nbsp; Now let’s move onto retrieving and parsing the data.&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:52dc38aa-f5cb-472d-89b5-17e7d0377517" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; parseDocument xml &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; document &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; XDocument.Parse(xml)
  document.Root.Descendants()
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Seq.choose(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;fun&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; node &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; 
         &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; node.Element(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;user&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;then&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; status &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; HttpUtility.HtmlDecode(node.Element(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;text&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;).Value)
           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; image &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; node.Element(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;user&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;).Element(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;profile_image_url&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;).Value
           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; userName &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; node.Element(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;user&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;).Element(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;screen_name&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;).Value
           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; statusDate &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; DateTime.ParseExact(node.Element(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;created_at&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;).Value, 
                                                &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;ddd MMM dd HH:mm:ss +0000 yyyy&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, 
                                                CultureInfo.CurrentCulture)
           Some { UserName &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; userName; ProfileImage &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; image; Status &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; status; StatusDate &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; statusDate}
         &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;else&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; None)  

&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; getUserTimeline userName password &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
  async { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; request &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; WebRequest.Create timelineUrl :&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;?&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; HttpWebRequest
          &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;do&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; request.Credentials &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;-&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; NetworkCredential(userName, password)
          
          &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;use&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; response &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; request.AsyncGetResponse()
          &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;use&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; reader &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; StreamReader(response.GetResponseStream())
          &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; xml &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; reader.AsyncReadToEnd()
          
          &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; parseDocument xml
        }&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;In the above code, we create a WebRequest, setting the credentials through Basic Authentication.&amp;nbsp; We’ll cover this approach for now with some attention to OAuth at some point in the relative near future.&amp;nbsp; After setting the identity, we get the response stream and read it to the end.&amp;nbsp; This gives us XML to parse and by using LINQ to XML, we’re able to iterate through each node, and if the user node is not null then we parse out each element for which we’re concerned.&lt;/p&gt;

&lt;p&gt;Now that we have the ability to do some asynchronous behavior, what do we do about it?&amp;nbsp; In previous posts, I’ve taken the road of running these operations in parallel, which then runs all instances and returns an answer.&amp;nbsp; But, if we’re&amp;nbsp; only executing one instance, how do we enlist in asynchronous behavior overall?&amp;nbsp; To illustrate, I’ll create a simple Windows Forms application to display the tweets in a textbox and have a refresh button to call the above function to repopulate our textbox.&amp;nbsp; First, let’s create the basic skeleton:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:40f65dc8-8a32-40b7-9322-de876ba1e274" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; form &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Form(Visible&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, TopMost &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, Width&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;500&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, Height&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;300&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)

&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; status &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; TextBox(Multiline&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, ScrollBars&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ScrollBars.Vertical)
form.Controls.Add status
status.Width &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;-&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;400&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
status.Height &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;-&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;300&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;

&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; refresh &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Button(Text&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;Refresh&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
form.Controls.Add refresh
refresh.Left &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;-&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;410&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
refresh.Top &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;-&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;10&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Now that we have a basic skeleton, let’s add the behavior to the button to refresh our textbox.&amp;nbsp; To do this, we simply add a handler to the button click event.&amp;nbsp; In there, we will call Async.RunWithContinuations which gives us the ability to handle not only the successful case, but also should an exception be thrown or some form of cancelation occurs.&amp;nbsp; Before we look at the implementing code, let’s look at the signature of RunWithContinuations:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:171314ff-f655-4ee9-b2fe-aa1f634cc891" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Async.RunWithContinuations;;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;val&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; it :
  (&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;a -&amp;gt; unit) * (exn -&amp;gt; unit) * (OperationCanceledException -&amp;gt; unit) *&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;  Async&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;a&amp;gt; -&amp;gt; unit = &amp;lt;fun:clo@0-42&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;What this tells us is that it takes a success continuation as the first argument, the exception continuation as the second argument, the cancelation continuation as the third, and then finally the asynchronous operation.&amp;nbsp; This allows us to uniquely handle each type of event, should they occur.&amp;nbsp; In this case, our success continuation should populate the textbox, whereas both the cancelation and the exceptional case should show a message box containing the exception.&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:f42edafa-9e26-4ecd-a7c1-0e1c225a8884" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;refresh.Click.Add
   (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;fun&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; args &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
      status.Text &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;-&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;""&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
      Async.RunWithContinuations(
        (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;fun&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; res &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; 
           res &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Seq.iter(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;fun&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; item &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; status.Text &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;-&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; sprintf &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;User: %s - %s\r\n\r\n%s&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; item.UserName item.Status status.Text )),
        (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;fun&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; exn &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; MessageBox.Show(sprintf &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;An error occurred: %A&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; exn) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ignore),
        (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;fun&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; cxn &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; MessageBox.Show(sprintf &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;A cancellation error ocurred: %A&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; cxn) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ignore),
        (getUserTimeline &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;username&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;password&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)))&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt; As you can see, the behavior is rather straight forward to define handlers for our three cases.&amp;nbsp; Lastly, we provide our credentials to the getUserTimeline function and then when the button is clicked, we’ll get results much like the following screenshot.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://codebetter.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/matthew.podwysocki/image_5F00_thumb_5F00_4626DF96.png" style="border-width: 0px; display: inline;" title="image" alt="image" mce_src="http://codebetter.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/matthew.podwysocki/image_5F00_thumb_5F00_4626DF96.png" border="0" height="259" width="461"&gt; &lt;/p&gt;

&lt;p&gt; Then we can keep pressing the refresh button and then asynchronously, it will handle the behavior appropriately, either in success or in failure.&amp;nbsp;&amp;nbsp; &lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This is a pretty simply and naive application, but it can show how you can take advantage of asynchronous behavior using the Async Workflows in F#.&amp;nbsp; By being able to have the F# libraries handle the exceptions and cancelation, a major source of errors is reduced by quite a bit.&amp;nbsp; Giving us the power then to handle each one of these scenarios, either in success, failure or cancelation is a great concept.&amp;nbsp; There is still more yet to be covered including Futures and the inclusion of the Task Parallel Library as well as other adventures into Twitter and Bing APIs.&lt;/p&gt;
&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7131022" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Concurrency/default.aspx">Concurrency</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Functional+Programming/default.aspx">Functional Programming</category></item><item><title>Axum – Ping Pong with Ordered Interaction Points</title><link>http://weblogs.asp.net/podwysocki/archive/2009/06/04/axum-ping-pong-with-ordered-interaction-points.aspx</link><pubDate>Thu, 04 Jun 2009 06:22:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7107807</guid><dc:creator>podwysocki</dc:creator><author>podwysocki</author><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/podwysocki/rsscomments.aspx?PostID=7107807</wfw:commentRss><comments>http://weblogs.asp.net/podwysocki/archive/2009/06/04/axum-ping-pong-with-ordered-interaction-points.aspx#comments</comments><description>&lt;p&gt;&lt;b&gt;UPDATE: Removed code and explained that what I had was not intended behavior&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;After a slight diversion into F# mailbox processing, it’s time to come back to talk a little bit more about &lt;a href="http://msdn.microsoft.com/en-us/devlabs/dd795202.aspx" mce_href="http://msdn.microsoft.com/en-us/devlabs/dd795202.aspx"&gt;Axum&lt;/a&gt;.&amp;nbsp; In &lt;a href="http://weblogs.asp.net/blogs/matthew.podwysocki/archive/2009/05/15/axum-ping-pong-with-dataflow-networks.aspx" mce_href="http://weblogs.asp.net/blogs/matthew.podwysocki/archive/2009/05/15/axum-ping-pong-with-dataflow-networks.aspx"&gt;our last Axum post&lt;/a&gt;, we discussed using dataflow networks to clean up our canonical Ping-Pong example.&amp;nbsp; This time, we’ll try another approach using ordered interaction points.&lt;/p&gt;
&lt;h2&gt;A Little Housekeeping&lt;/h2&gt;
&lt;p&gt;Before we get started with our full demonstration, let’s take a brief look at some concepts that will come into play for this solution.&amp;nbsp; In our previous example using data flow networks, we a shared-nothing approach between these two agents.&amp;nbsp; This time, let’s introduce the concept of domains.&amp;nbsp; A domain in Axum allows for a group of agents to safely share data while shielding this state from the outside world.&amp;nbsp; Like normal classes, domains can have such things as fields and methods, but also, we can declare agents.&amp;nbsp; We’ll discuss how this comes into play later on in the post.&lt;/p&gt;
&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:96c280ff-11b1-4ecf-9f15-e1bedcba3f80" class="wlWriterEditableSmartContent"&gt;
&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;domain&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; A {
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; fieldName;
    ...
}&lt;/span&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;Another key concept to understand is reader and writer agents.&amp;nbsp; Typically, when dealing with shared state of some sort, we have a notion of a reader-writer lock.&amp;nbsp; This synchronization technique allows access to the shared state as one to many readers or a single writer to ensure consistency of that shared resource.&amp;nbsp; Agents in Axum also follow this notion where a reader agent is only allowed to read shared state and a writer agent can both read and write to domain state.&lt;/p&gt;
&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:4a4397cc-e03a-4451-bd2d-9508db75b514" class="wlWriterEditableSmartContent"&gt;
&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;domain&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; A {
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; fieldName;
    
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;reader&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;agent&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; A1 { ... } &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Can read fieldName&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;writer&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;agent&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; A2 { ... } &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Can read/write fieldName&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;One more concept that needs to be covered before our solution is the idea of hosts.&amp;nbsp; By using a host, we are able to associate an agent’s type with a particular instance in the domain.&amp;nbsp; For example when we look at the following code, what we’re doing is when someone asks for our A1 domain with an address of myA1, we attach it to the current domain and then return the associated C channel endpoint.&lt;/p&gt;
&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:0eb43e6e-275c-4ef7-870b-e0bdcaa95416" class="wlWriterEditableSmartContent"&gt;
&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Host&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;A1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;myA1&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;/span&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;We can connect to this host then through a mechanism such as the following:&lt;/p&gt;
&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:05c9ac41-79ea-462d-ba01-67c7fd03c618" class="wlWriterEditableSmartContent"&gt;
&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; chan &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; C(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;myA1&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;/span&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;Bringing this all together, let’s look at the Ping-Pong example through these eyes.&lt;/p&gt;
&lt;h2&gt;Getting to the Solution&lt;/h2&gt;
&lt;p&gt;In this solution, we’ll introduce the aspect of ordered interaction points.&amp;nbsp; This is an interaction point that acts as both a source and a target and the keyword being ordered which means that the order of messages is preserved.&amp;nbsp; To declare one, use the OrderedInteractionPoint&amp;lt;T&amp;gt; class such as the following:&lt;/p&gt;
&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:8ce2b884-a0f4-428f-8c3d-a02d360d0fcf" class="wlWriterEditableSmartContent"&gt;
&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ip &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; OrderedInteractionPoint&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;();&lt;/span&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;Now, let’s get to our solution.&amp;nbsp; The main application is no different, but where we will find differences is the interaction between the Ping and Pong agents.&amp;nbsp; As the code for that part hasn’t changed, let’s focus on the interaction between the ping and pong inside our domain.&amp;nbsp; First, let’s define the domain and we’ll call it the PingPongDomain (imaginative, I know).&amp;nbsp; In this domain, we need to set up the hosting for the Pong agent at the “Pong” address as well as the ordered interaction points for the ping and the pong.&lt;/p&gt;
&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:18474123-bd32-4734-93d1-5f0dcbe3cc4a" class="wlWriterEditableSmartContent"&gt;
&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;domain&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; PingPongDomain
{
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; PingPongDomain()
    {
        Host&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Pong&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;Pong&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);
    }
    
    OrderedInteractionPoint&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Signal&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ping &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; OrderedInteractionPoint&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Signal&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;();
    OrderedInteractionPoint&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Signal&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; pong &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; OrderedInteractionPoint&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Signal&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;();&lt;/span&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;Once we have this defined for our domain, our Ping and Pong agents inside this domain will have access to these points.&amp;nbsp; Since the Ping agent will ultimately both read and write messages, but using the immutable data type as the message type, we need not define it as a writer, but instead as a reader.&amp;nbsp; Let’s define that below.&lt;/p&gt;
&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:3ceec151-c19e-4126-ad14-6d1e344db4c7" class="wlWriterEditableSmartContent"&gt;
&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;reader&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;agent&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Ping : &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;channel&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; PingPongStatus
    {
        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Ping()
        {
            PrimaryChannel::HowMany &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;==&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Process;
        }
        
        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Signal Process(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; iters)
        {
            &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Create pong&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; chan &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; PingPong(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;Pong&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);

           &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Send pings and receive pongs&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;for&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; i &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;; i &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; iters; i&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;++&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
           {
               ping &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Signal.Value;
               &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;receive&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(pong);
               Console.WriteLine(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;ping received pong&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);
           }

            chan::Done &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Signal.Value;
            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Signal.Value;
        }
    }&lt;/span&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;You’ll notice that our code doesn’t look too much different than our previous example, except for connecting to the PingPongChannel with the “Pong” address that we defined in our domain above.&amp;nbsp; The other change is that we are sending a message on the ping ordered interaction point and receiving a message on the pong instance.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Moving along to our Pong agent, once again, the code does not deviate much.&amp;nbsp; But, as we are reading and writing our domain state by sending messages that are immutable, we could declare ourselves as a reader agent.&amp;nbsp; We will continuously receive messages either on the ping ordered interaction point or we will receive a message on the Done port on the primary channel.&amp;nbsp; The code will look something like the following.&lt;/p&gt;
&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:9cdf6e01-5880-4182-af37-93af359a6771" class="wlWriterEditableSmartContent"&gt;
&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;reader&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;agent&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Pong : &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;channel&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; PingPong
    {
        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Pong()
        {
            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;while&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;receive&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
            {
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;from&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; PrimaryChannel::Done:
                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;from&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ping:
                    Console.WriteLine(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;pong received ping&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);
                    pong &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Signal.Value;
                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;break&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;
            }
        }
    }&lt;/span&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;Now that we have a solution, but, unfortunately due to a bug, this doesn’t work because the compiler cannot distinguish whether the state is immutable or not.&amp;nbsp; But, we can get it to run with an escape hatch.&lt;/p&gt;
&lt;h2&gt;Being Unsafe in a Safe Way&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://weblogs.asp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/matthew.podwysocki/image_5F00_12F5BE77.png" mce_href="http://weblogs.asp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/matthew.podwysocki/image_5F00_12F5BE77.png"&gt;&lt;img src="http://weblogs.asp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/matthew.podwysocki/image_5F00_thumb_5F00_1CDAAFE2.png" style="border-width: 0px; display: inline; margin-left: 0px; margin-right: 0px;" title="image" alt="image" mce_src="http://weblogs.asp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/matthew.podwysocki/image_5F00_thumb_5F00_1CDAAFE2.png" align="left" border="0" height="162" width="244"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;As I stated before, Axum does have a notion of an escape hatch when it comes to code that allows you to execute code that might modify shared state through the use of the &lt;i&gt;unsafe&lt;/i&gt; keyword.&amp;nbsp; Most times it’s better to be safe than sorry in this regard, but in this example, it fits quite well.&amp;nbsp; You can think of this unsafe escape hatch much like the Haskell &lt;a href="http://haskell.org/ghc/docs/latest/html/libraries/base/System-IO-Unsafe.html" mce_href="http://haskell.org/ghc/docs/latest/html/libraries/base/System-IO-Unsafe.html"&gt;unsafePerformIO&lt;/a&gt; function.&amp;nbsp; This function in Haskell is the back door into the IO monad which allows an IO computation to be performed at any time.&amp;nbsp; And like our unsafe keyword, in order for this to be safe, we should be free of side effects and not dependent upon the environment.&lt;/p&gt;
&lt;p&gt;With this in mind, let’s rewrite the example using the unsafe construct.&amp;nbsp; First, let’s look at the Ping agent and how we might make that a little unsafe, but yet fully operational:&lt;/p&gt;
&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:5c26b87d-7ef9-42e8-b3f3-dcde519eca90" class="wlWriterEditableSmartContent"&gt;
&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;agent&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Ping : &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;channel&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; PingPongStatus
{
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Ping()
    {
        PrimaryChannel::HowMany &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;==&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Process;
    }
    
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Signal Process(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; iters)
    {
        &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Create pong&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; chan &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; DefaultCommunicationProvider.Connect&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;PingPong&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;Pong&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);
        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;unsafe&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
        {
            &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Send pings and receive pongs&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;for&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; i &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;; i &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; iters; i&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;++&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
            {
                ping &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Signal.Value;
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;receive&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(pong);
                Console.WriteLine(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;ping received pong&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);
            }
        }
        chan::Done &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Signal.Value;
        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Signal.Value;
    }
}&lt;/span&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;By simply wrapping our for loop in the unsafe block, we are able to send messages to our ping ordered interaction point and receive from our pong ordered interaction point where we weren’t allowed to in the above example.&amp;nbsp; The same applies for our Pong agent as well.&amp;nbsp; We can wrap the while loop receiving messages in an unsafe block so that we can receive from the ping ordered interaction point and then send a signal to the pong ordered interaction point.&lt;/p&gt;
&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:58baac6c-27a6-461b-8c5e-9ccae784fed4" class="wlWriterEditableSmartContent"&gt;
&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;agent&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Pong : &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;channel&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; PingPong
{
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Pong()
    {
        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;unsafe&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; 
        {
            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;while&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;receive&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
            {
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;from&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; PrimaryChannel::Done:
                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;from&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ping:
                    Console.WriteLine(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;pong received ping&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);
                    pong &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Signal.Value;
                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;break&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;
            }
        }
    }
}&lt;/span&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;Running our sample, we get our expected results.&amp;nbsp; You can find the complete source code to this example &lt;a href="http://gist.github.com/122797" mce_href="http://gist.github.com/122797"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://weblogs.asp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/matthew.podwysocki/image_5F00_6F893FDE.png" mce_href="http://weblogs.asp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/matthew.podwysocki/image_5F00_6F893FDE.png"&gt;&lt;img src="http://weblogs.asp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/matthew.podwysocki/image_5F00_thumb_5F00_53980AE6.png" style="border-width: 0px; display: inline;" title="image" alt="image" mce_src="http://weblogs.asp.net/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/matthew.podwysocki/image_5F00_thumb_5F00_53980AE6.png" border="0" height="252" width="495"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Unlike Erlang and other shared-nothing messaging approaches, Axum allows for shared domain state through tightly controlled access.&amp;nbsp; By doing so, we keep the safety aspect of messaging through such notions of a reader-writer lock.&amp;nbsp; Of course, there is an escape hatch for those who truly understand their application and the ramifications of what they are doing.&amp;nbsp; As you can see, Axum has a wide array of solving even the most simple and canonical examples of actor model concurrency.&amp;nbsp; There is still more yet to cover including asynchronous behavior and an exploration of the Auction example that I gave in F#.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/devlabs/dd795202.aspx" mce_href="http://msdn.microsoft.com/en-us/devlabs/dd795202.aspx"&gt;Download it today&lt;/a&gt;, use it in anger and &lt;a href="http://social.msdn.microsoft.com/Forums/en/axum." mce_href="http://social.msdn.microsoft.com/Forums/en/axum."&gt;give the team feedback&lt;/a&gt; as to help shape what actor model concurrency might look like on the .NET platform.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7107807" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Axum/default.aspx">Axum</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Concurrency/default.aspx">Concurrency</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Erlang/default.aspx">Erlang</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Haskell/default.aspx">Haskell</category></item><item><title>When Side Effects and Laziness Collide</title><link>http://weblogs.asp.net/podwysocki/archive/2009/06/02/when-side-effects-and-laziness-collide.aspx</link><pubDate>Tue, 02 Jun 2009 16:34:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7106197</guid><dc:creator>podwysocki</dc:creator><author>podwysocki</author><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/podwysocki/rsscomments.aspx?PostID=7106197</wfw:commentRss><comments>http://weblogs.asp.net/podwysocki/archive/2009/06/02/when-side-effects-and-laziness-collide.aspx#comments</comments><description>&lt;p&gt;While working on a side project recently, I came to rediscover some of the consequences of one of my earlier posts on &lt;a href="http://codebetter.com/blogs/matthew.podwysocki/archive/2008/09/12/side-effects-and-functional-programming.aspx" mce_href="http://codebetter.com/blogs/matthew.podwysocki/archive/2008/09/12/side-effects-and-functional-programming.aspx"&gt;“Side Effects and Functional Programming”&lt;/a&gt;.&amp;nbsp; It’s important that we realize that when we are creating our programs to beware of lazy evaluation and side effects.&amp;nbsp; &lt;/p&gt;

&lt;h2&gt;Adding a Wrinkle&lt;/h2&gt;

&lt;p&gt;Consider the following example.&amp;nbsp; We need to be able to get the stream data from a given web request for a given URL.&amp;nbsp; From there, we will take the stream of data and read each line and return it as a collection.&amp;nbsp; Typically if we’re going to do this through F#, we’d use a sequence expression to lazily read through each line and return it as an IEnumerable&amp;lt;string&amp;gt;.&amp;nbsp; But, let’s add an extra wrinkle to this.&amp;nbsp; What if we want to do this in a non-thread blocking&amp;nbsp; asynchronous scenario?&amp;nbsp; This adds an extra wrinkle to this in terms of managing the lifetime of our objects.&amp;nbsp; We might write the code such as the following:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:df9ccf0b-5a65-4b47-a03c-4a2f1ab38ac8" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;open&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; System.IO
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;open&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; System.Net

&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; getStreamData (uri:string) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
  async { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; request &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; WebRequest.Create uri 
          &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; response &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; request.AsyncGetResponse()
          
          &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; seq { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;use&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; stream &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; response.GetResponseStream()
                       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;use&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; reader &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; StreamReader(stream)
                       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;while&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; not reader.EndOfStream &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;do&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;yield&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; reader.ReadLine() } 
        }&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;What we’re doing is putting a sequence expression inside of an asynchronous expression.&amp;nbsp; We must bind the response outside of the sequence expression due to the fact that we are doing this in an asynchronous fashion.&amp;nbsp; Once inside a sequence expression, a bind has a different meaning.&amp;nbsp; But, there’s a problem with this code.&amp;nbsp; Can you spot it?&amp;nbsp; &lt;/p&gt;

&lt;p&gt;The problem lies in the fact that we’re not explicitly disposing the response, which implements IDisposable.&amp;nbsp; My rule of thumb when flushing out my design is that if a class implements IDisposable and I ultimately control its lifetime, then I must wrap it in a using block.&amp;nbsp; If you read the documentation, you’ll realize that it’s not totally necessary when dealing with an HttpWebRequest to call Dispose, but it is when you’re dealing with an FtpWebRequest.&amp;nbsp; Because I don’t make any distinction in this code, calling Dispose is a must.&amp;nbsp; We might be tempted then to change the code to the following:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:63ef9ca0-eea0-4e04-917c-87c8e1938865" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;open&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; System.IO
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;open&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; System.Net

&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; getStreamData (uri:string) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
  async { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; request &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; WebRequest.Create uri 
          &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;use&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; response &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; request.AsyncGetResponse()
          
          &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; seq { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;use&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; stream &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; response.GetResponseStream()
                       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;use&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; reader &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; StreamReader(stream)
                       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;while&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; not reader.EndOfStream &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;do&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;yield&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; reader.ReadLine() } 
        }&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Running through a quick example using F# interactive, we’d get the following result:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:33da5bce-55e7-4aa7-823d-48e68e34932c" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Async.RunSynchronously (getStreamData &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;http://www.bing.com&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;val&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; it : seq&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
  Error: Cannot access a disposed object.
Object name: &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;System.Net.HttpWebResponse&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;The problem now becomes that our response binding now will be disposed by the time that I iterate the results of the sequence expression.&amp;nbsp; Remember that our evaluation of the sequence expression is lazy, so by the time I’m ready to iterate, the response has already had its Dispose called.&amp;nbsp; So, where does that leave us?&amp;nbsp; &lt;/p&gt;

&lt;p&gt;Well, there are several things that we could do here.&amp;nbsp; First, we could copy the response inside of our sequence expression and bind that to a using block.&amp;nbsp; This would ensure that by the time we’re finished, we would properly dispose the response.&amp;nbsp; That code might look like the following:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:ff768c0b-11b5-49ee-92c7-c748fc4d7308" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;open&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; System.IO
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;open&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; System.Net

&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; getStreamData (uri:string) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
  async { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; request &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; WebRequest.Create uri 
          &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; response &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; request.AsyncGetResponse()
          
          &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; seq { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;use&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; response&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt; = response&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;use&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; stream &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; response&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;.GetResponseStream()&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;use&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; reader &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; StreamReader(stream)
                       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;while&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; not reader.EndOfStream &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;do&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;yield&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; reader.ReadLine() } 
        }&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;This approach will work, unlike the previous example.&amp;nbsp; By copying in this reference, we can ensure that the response will be disposed by the time we’re finished with our sequence expression.&amp;nbsp; Although this works, it has a certain code smell to me.&amp;nbsp; This code smell revolves around copying these references and there is a certain danger in doing so in terms of managing the lifetime.&amp;nbsp; Instead, could we try another approach, perhaps more eager?&lt;/p&gt;

&lt;h2&gt;From Lazy to Eager&lt;/h2&gt;

&lt;p&gt;Another approach we could take with this is to do away with the idea of lazy I/O in this solution altogether.&amp;nbsp; Instead, how about something as simple as a list comprehension instead of a sequence expression?&amp;nbsp; The code might then look like the following:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:72a0d212-fcf5-4e8d-9546-6cc9ff82ac43" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;open&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; System.IO
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;open&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; System.Net

&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; getStreamData (uri:string) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
  async { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; request &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; WebRequest.Create uri 
          &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;use&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; response &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; request.AsyncGetResponse()
          
          &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; [ &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;use&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; stream &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; response.GetResponseStream()
                   &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;use&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; reader &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; StreamReader(stream)
                   &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;while&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; not reader.EndOfStream &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;do&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;yield&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; reader.ReadLine() ] 
        }&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Now what we have is that we have the use binding on our response and stream.&amp;nbsp; At the end of our function, we simply use a list comprehension instead of the sequence comprehension which in this case gives us the benefit of eager evaluation.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;When dealing with asynchronous expressions mixed with sequence expressions can cause problems due to object lifetimes.&amp;nbsp; As I’ve had in my earlier post, it’s best to avoid such scenarios if possible and instead, focus on an eager approach.&amp;nbsp; The savings you get here is you have to worry less about the resource lifetimes which may or may not be in scope by the time you’re ready to execute the sequence expression.&amp;nbsp; The approach using the list comprehension should be the preferred solution.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7106197" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Concurrency/default.aspx">Concurrency</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Functional+Programming/default.aspx">Functional Programming</category></item><item><title>Actors in F# – The Bounded Buffer Problem</title><link>http://weblogs.asp.net/podwysocki/archive/2009/05/28/actors-in-f-the-bounded-buffer-problem.aspx</link><pubDate>Thu, 28 May 2009 06:58:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7099636</guid><dc:creator>podwysocki</dc:creator><author>podwysocki</author><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/podwysocki/rsscomments.aspx?PostID=7099636</wfw:commentRss><comments>http://weblogs.asp.net/podwysocki/archive/2009/05/28/actors-in-f-the-bounded-buffer-problem.aspx#comments</comments><description>&lt;p&gt;In the &lt;a href="http://codebetter.com/blogs/matthew.podwysocki/archive/2009/05/20/f-actors-revisited.aspx" mce_href="http://codebetter.com/blogs/matthew.podwysocki/archive/2009/05/20/f-actors-revisited.aspx"&gt;previous post&lt;/a&gt;, I covered an example of an auction simulation using asynchronous message passing and a shared nothing approach using the MailboxProcessor class in F#.&amp;nbsp; The auction example was a great piece to demonstrate scalability by adding additional clients to create a sort of bidding war between them.&amp;nbsp; Once again, with this approach, we’ve eliminated the need for locks and other concurrency primitives.&lt;/p&gt;

&lt;p&gt;This time, let’s take another canonical example of a &lt;a href="http://en.wikipedia.org/wiki/Producer-consumer_problem" mce_href="http://en.wikipedia.org/wiki/Producer-consumer_problem"&gt;Bounded Buffer&lt;/a&gt; and look at some of the design patterns around this.&lt;/p&gt;

&lt;h2&gt;The Bounded Buffer&lt;/h2&gt;

&lt;p&gt;The goal of this post is to walk through an example of actor model concurrency of the &lt;a href="http://en.wikipedia.org/wiki/Producer-consumer_problem" mce_href="http://en.wikipedia.org/wiki/Producer-consumer_problem"&gt;canonical Bounded Buffer&lt;/a&gt; which is another &lt;a href="http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk/docs/examples/actors/boundedbuffer.scala" mce_href="http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk/docs/examples/actors/boundedbuffer.scala"&gt;example given in Scala&lt;/a&gt;.&amp;nbsp; The intent of this demo is to store and retrieve items in a buffer (rather simple actually).&amp;nbsp; Given this example, we’ll walk through how we might implement this using the constructs in F#.&amp;nbsp; One important aspect of this solution is to not post messages asynchronously as before, but instead, to post a message and await the reply.&lt;/p&gt;

&lt;p&gt;Without further ado, let’s get into the code.&amp;nbsp; As before, we have a few utility functions that will be quite handy for this journey.&amp;nbsp; Much like we defined the (&amp;lt;—) operator last time for posting messages, I’d like one for posting and waiting for a reply.&amp;nbsp; In addition, I need a way to accomplish currying for reasons you will see later.&amp;nbsp; One thing that has irked me on occasion is the confusion between partial application and currying, which &lt;a href="http://codebetter.com/blogs/matthew.podwysocki/archive/2009/04/23/functional-c-composing-through-partial-application.aspx" mce_href="http://codebetter.com/blogs/matthew.podwysocki/archive/2009/04/23/functional-c-composing-through-partial-application.aspx"&gt;I’ve covered earlier&lt;/a&gt;.&amp;nbsp; Getting back to the issue at hand, let’s look at the code for that:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:9c97a4a8-b225-4ab1-bba8-b15fb7561656" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Curry the arguments&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; curry f x y &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; f (x, y)

&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Asynchronous post&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) (m:_ MailboxProcessor) msg &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; m.Post msg

&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Post and reply operator&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) (m:_ MailboxProcessor) msg &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; m.PostAndReply(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;fun&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; replyChannel &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; msg replyChannel)&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;As you’ll notice, I put the two operators, the asynchronous post and the post and reply operators, the former not being needed for this post.&amp;nbsp; The PostAndReply method gives a way to post a message and wait for the reply.&amp;nbsp; A temporary reply channel is created and that forms part of our message.&amp;nbsp; This reply channel is an AsyncReplyChannel&amp;lt;T&amp;gt; which supports one function of Reply which we will use later.&amp;nbsp; This message is then sent back to the caller as the result.&lt;/p&gt;

&lt;p&gt;Next, we need to define the messages we will be processing as part of this bounded buffer.&amp;nbsp; Each of these messages define operations that our buffer supports, namely put, get and stop.&amp;nbsp; Let’s take a look at these in detail:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:8ea5291e-2f79-42dd-89f7-b98fd2ea3048" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;type&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;a BufferMessage = Put of &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;a &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;*&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; unit AsyncReplyChannel 
                      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Get &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;of&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;a AsyncReplyChannel &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Stop &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;of&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; unit AsyncReplyChannel&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;As you will notice, each of these has an associated AsyncReplyChannel part to the defined message.&amp;nbsp; This is to allow me to reply to each of the callers in turn.&amp;nbsp; The Put and Stop both have reply channels that take no associated data, so we can create them as an AsyncReplyChannel&amp;lt;unit&amp;gt;.&amp;nbsp;&amp;nbsp; The Put message allows us to put a value into the buffer, the Get allows us to retrieve those values in turn, and the Stop allows us to stop the mailbox.&amp;nbsp; &lt;/p&gt;

&lt;p&gt;Let’s move on to the heart of the matter, the actual bounded buffer.&amp;nbsp; This class takes in a buffer size and then we expose methods that allow us to put values in the buffer, get values from the buffer and stop the mailbox.&amp;nbsp; Below is how the code might look:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:f5a1d413-8ab6-43a4-acac-db7d8b5775d7" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;type&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;a BoundedBuffer(N:int) =&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;  
  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; buffer &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;     
    MailboxProcessor.Start(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;fun&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; inbox &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; buf:&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;a array = Array.zeroCreate N&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;rec&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; loop &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt; out n =&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        async { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; msg &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; inbox.Receive()
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;match&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; msg &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;with&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Put (x, replyChannel) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;when&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; n &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; N &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                    Array.set buf &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt; x&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                    replyChannel.Reply ()
                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; loop ((&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt; + 1) % N) out (n + 1)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                    
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Get replyChannel &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;when&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; n &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; r &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Array.get buf out
                    replyChannel.Reply r
                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; loop &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt; ((out + 1) % N) (n - 1)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                    
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Stop replyChannel &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; replyChannel.Reply(); &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; () }
      loop &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
      
  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;member&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; this.Put(x:&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;a) = buffer &amp;lt;-&amp;gt; curry Put x&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;member&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; this.Get() &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; buffer &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Get
  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;member&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; this.Stop() &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; buffer &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Stop&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Inside our BoundedBuffer class, we create the buffer which then creates an initialized array.&amp;nbsp; Because array contents are mutable, there is no sense in putting this as part of our processing loop.&amp;nbsp; Instead, we’ll focus on the input index, the output index and the number of items in the buffer as part of our processing loop.&amp;nbsp; When we receive the Put message when the number of items in the buffer is less than the buffer size, we set the value at the specified input index, return a reply back to the caller, and then loop with an increment to our index with a modulo of the buffer size as well as the number of items in the buffer.&amp;nbsp; In receiving a Get message when the number of items in the buffer is greater than zero, we get the item at the output index, send the reply back to the caller with the value, and then loop with an increment to the output index with a modulo as well as decrementing the number of items in our buffer.&amp;nbsp; Finally, should we receive a Stop, we simply reply back to the caller and return.&lt;/p&gt;

&lt;p&gt;We created three methods to wrap this functionality for outside consumption.&amp;nbsp; The Put method takes in the item to post to the buffer, and then we simply do a PostAndReply with our Put message and our item to post.&amp;nbsp; I used currying here because the Put message requires two parameters, the item to put as well as the reply channel.&amp;nbsp; In this case, my operator already provides that reply channel, so I only need to supply the item to put.&amp;nbsp; Both the Get and the Stop methods are fairly straight forward as they post their respective messages with their private reply channels.&lt;/p&gt;

&lt;p&gt;How does this work?&amp;nbsp; Let’s fire up F# interactive and take a look with an example of posting a few items to our buffer and then retrieving them.&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:089376af-9469-4223-a506-f4085607616a" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; buffer &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; int BoundedBuffer &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;42&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;;

&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;val&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; buffer : int BoundedBuffer

&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; buffer.Put &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;12&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;val&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; it : unit &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ()
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; buffer.Put &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;34&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;val&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; it : unit &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ()
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; buffer.Put &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;56&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;val&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; it : unit &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ()
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; buffer.Get();;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;val&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; it : int &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;12&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; buffer.Get();;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;val&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; it : int &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;34&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; buffer.Get();;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;val&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; it : int &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;56&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; buffer.Stop();;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;val&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; it : unit &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ()&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;What I did was create a BoundedBuffer that handled integers with a buffer size of 42.&amp;nbsp; Then I posted three values, 12, 34 and 56.&amp;nbsp; After putting these values into our buffer, I then retrieved each in the order in which it was placed into our buffer.&amp;nbsp; Finally, I stopped the buffer.&amp;nbsp; The complete source code to this example can be found &lt;a href="http://gist.github.com/118484" mce_href="http://gist.github.com/118484"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Once again, we can create rather interesting solutions using this shared nothing asynchronous message passing approach in F#.&amp;nbsp; This solution involving the bounded buffer is no exception.&amp;nbsp; How might this solution look in Axum?&amp;nbsp; In due time, we will approach this as well as our Auction example from the previous post.&amp;nbsp; There are a lot of Axum items to cover especially in regards to asynchronous methods and ordered interaction points, so stay tuned.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7099636" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Axum/default.aspx">Axum</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Concurrency/default.aspx">Concurrency</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Erlang/default.aspx">Erlang</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Functional+Programming/default.aspx">Functional Programming</category></item><item><title>F# Actors Revisited</title><link>http://weblogs.asp.net/podwysocki/archive/2009/05/20/f-actors-revisited.aspx</link><pubDate>Wed, 20 May 2009 05:25:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7093288</guid><dc:creator>podwysocki</dc:creator><author>podwysocki</author><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/podwysocki/rsscomments.aspx?PostID=7093288</wfw:commentRss><comments>http://weblogs.asp.net/podwysocki/archive/2009/05/20/f-actors-revisited.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;UPDATE: Removed ref cells to use two recursive loops&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;a href="http://codebetter.com/blogs/matthew.podwysocki/archive/2009/05/15/axum-ping-pong-with-dataflow-networks.aspx" mce_href="http://codebetter.com/blogs/matthew.podwysocki/archive/2009/05/15/axum-ping-pong-with-dataflow-networks.aspx"&gt;previous post&lt;/a&gt;, I covered briefly about the actor model in F#.&amp;nbsp; This style of concurrency, using asynchronous message passing and a shared-nothing approach through the use of mailboxes is a pretty powerful mechanism for achieving scalability.&amp;nbsp; With a shared-nothing approach, we can remove the need for such concurrency primitives such as locks.&amp;nbsp; &lt;/p&gt;

&lt;p&gt;Taking cues from Erlang, F# has the capabilities as well through the use of the MailboxProcessor class.&amp;nbsp; In this post, let’s walk through a canonical example and explain some of the design patterns around this.&lt;/p&gt;

&lt;h2&gt;Mailboxes, Etc&lt;/h2&gt;

&lt;p&gt;Before we begin, let’s make sure we have some of the basics down.&amp;nbsp; As I stated above, the approach here is that inter-agent communication is accomplished through a shared-nothing asynchronous message passing system.&amp;nbsp; Each of these agents have a mailbox, which is nothing more than a queue of messages sent by other processes.&amp;nbsp; These messages are then retrieved via either a scan or receive approach, depending if you wish to continue receiving messages.&amp;nbsp; To determine which message we received, we do basic pattern matching against our given message types and decide how we want to handle it.&amp;nbsp;&amp;nbsp; To continue processing, we then recurse the function again to keep sending and receiving.&amp;nbsp; We can send any number of pieces of data as part of these messages.&amp;nbsp; For our example, we’ll implement the Auction example that comes from Scala.&lt;/p&gt;

&lt;h2&gt;Going Once…&amp;nbsp; Going Twice…&amp;nbsp; Sold!&lt;/h2&gt;

&lt;p&gt;Our goal in this post is to walk through implementing the &lt;a href="http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk/docs/examples/actors/auction.scala" mce_href="http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk/docs/examples/actors/auction.scala"&gt;Auction example&lt;/a&gt; which is an example given in Scala.&amp;nbsp; The intent of this demo is to show an online auction service using the shared-nothing asynchronous message passing.&amp;nbsp; We’ll have two clients bidding against each other to see who wins the particular item.&amp;nbsp; Given that Scala has library support for actors, this is an attempt to see how well F# can handle this as well.&amp;nbsp; The first impressions of the Scala model is that it’s much more focused on classes and objects than the F# version will be.&amp;nbsp; &lt;/p&gt;

&lt;p&gt;Without further ado, let’s start digging through the code.&amp;nbsp; First up, let’s get some utility functions out of the way to help us on our journey.&amp;nbsp; Instead of using the dot operator on some objects to send messages, I prefer the &amp;lt;—operator, as shown also in the Expert F# book.&amp;nbsp; Also, I need a way to deconstruct an option type so that I can deal with a bidder that may not exist yet.&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:a9a6d011-afec-4ce5-8126-d201e506028f" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) (m:_ MailboxProcessor) x &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; m.Post x
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; unSome (Some x) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; x&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Both of these functions should be rather self explanatory.&amp;nbsp; The unSome takes in an option type with Some value and returns the value.&amp;nbsp; Let’s move on to the messages that we need to define.&amp;nbsp; I have comments beside each as to define what each message signifies.&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:337570c3-d263-4b65-b730-4d6dc8eb70d6" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;type&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; AuctionMessage &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Offer &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;of&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; int &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;*&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; AuctionReply MailboxProcessor &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Make a bid&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Inquire &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;of&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; AuctionReply MailboxProcessor     &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Check the status&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;and&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; AuctionReply &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Status &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;of&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; int &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;*&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; DateTime &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Asked sum and expiration&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; BestOffer                &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Ours is the best offer&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; BeatenOffer &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;of&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; int       &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Yours is beaten by another offer&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; AuctionConcluded &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;of&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;      &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Auction concluded&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;      AuctionReply MailboxProcessor &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;*&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; AuctionReply MailboxProcessor
  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; AuctionFailed            &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Failed without any bids&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; AuctionOver              &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Bidding is closed&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;I decided to use a recursive type definition as to allow my AuctionMessage discriminated union to appear before my AuctionReply discriminated union, because both messages in AuctionMessage references a MailboxProcessor that handles the AuctionReply messages.&amp;nbsp; In F#, order does matter in which values are declared, so this is a quick way to get a readable output.&amp;nbsp; Next, we need to define some constants such as time to shutdown and our allowed bid increments:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:892e46dd-8e44-4337-91b8-b9aa8ba389dc" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; timeToShutdown &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;3000&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; bidIncrement &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;10&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;It’s now time to define our auction agent.&amp;nbsp; This will handle the overall orchestration of how the auction is handled.&amp;nbsp; This includes handling both the Offer and the Inquire messages as well as what happens when we fail to get a message within a certain time period.&amp;nbsp; Let’s step through the code now and then explain down below:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:e421756f-88e7-4fc2-a71e-90624b5af862" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; auctionAgent seller minBid closing &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; AuctionMessage MailboxProcessor(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;fun&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; inbox &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;rec&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; loop maxBid maxBidder &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
      async { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; msg &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; inbox.TryReceive((closing &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;-&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; DateTime.Now).Milliseconds)
              &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;match&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; msg &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;with&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Some ( Offer(bid, client) ) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; bid &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; maxBid &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;+&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; bidIncrement &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;then&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; maxBid &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; minBid &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;then&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; unSome maxBidder &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; BeatenOffer bid                  
                      client &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; BestOffer
                      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; loop bid (Some client)
                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;else&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                      client &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; BeatenOffer maxBid
                      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; loop maxBid maxBidder
                
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Some ( Inquire client ) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                    client &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Status(maxBid, closing)
                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; loop maxBid maxBidder
                
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; None &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; maxBid &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; minBid &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;then&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; reply &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; AuctionConcluded(seller, unSome maxBidder)
                      unSome maxBidder &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; reply
                      seller &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; reply
                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;else&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; seller &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; AuctionFailed
                    
                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; msg&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt; = inbox.TryReceive timeToShutdown&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;match&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; msg&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt; with&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Some ( Offer (_, client) ) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; 
                        client &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; AuctionOver
                        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; loop maxBid maxBidder
                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; None &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ()         
            }
    loop (minBid &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;-&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; bidIncrement) None)   &lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;It’s a bit of code to digest, but the gist of this is rather simple.&amp;nbsp; When creating an instance of this auction agent, we need a seller, a minimum bid and a closing time for the auction.&amp;nbsp; From this, we create our MailboxProcessor to handle AuctionMessage types.&amp;nbsp; Since we are continuously in a cycle of receiving messages and sending results, we have a recursive loop which carries our state for us.&amp;nbsp; This state, which we carry from recursive call to the next is our maximum bid and our maximum bidder at the time.&amp;nbsp; When we begin our call to this loop function, we start with the max bid of the minimum bid minus the bid increment and no maximum bidder.&amp;nbsp; &lt;/p&gt;

&lt;p&gt;When we are receiving messages, it’s important to handle any potential timeouts.&amp;nbsp; In this case, we use this timeout as a mechanism for determining when our auction is over.&amp;nbsp; In order to do this, we must use the TryReceive function instead of the Receive.&amp;nbsp; Let’s look at the differences below:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:d8419ddd-e2e2-49dc-b3ed-0f7d39659800" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Throws an exception if timeout is exceeded&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;member&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; MailboxProcessor.Receive : &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;?&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;timeout : int &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Async&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;msg&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Returns None if timeout is exceeded&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;member&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; MailboxProcessor.TryReceive : &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;?&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;timeout : int &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Async&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;msg option&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Since we need to know how to handle timeouts, it’s best to use the TryReceive approach.&amp;nbsp; If we receive an offer, we determine whether the bid is acceptable, meaning greater than our current maximum plus increment.&amp;nbsp; If it is, then we check whether the maximum bid is greater than the minimum, and if so, then send a message to the current maximum bidder with the BeatenOffer message.&amp;nbsp; If we receive an inquiry, we simply return a Status message back to the client with our current bid and how much time they have left.&amp;nbsp; Finally, if we don’t receive a message in the given timeframe, it’s time to wind down our auction.&amp;nbsp; If the maximum bid is greater than our minimum, our auction is a success and we let our maximum bidder and our seller know.&amp;nbsp; If, however, we don’t receive any bids, then our auction is considered a failure.&amp;nbsp; Finally, and additional offers received will be responded to with an AuctionOver message to indicate to the client that they are not the winner.&amp;nbsp; If this operation times out, we simply exit.&amp;nbsp; A bit of a mouthful, but fairly straight forward.&lt;/p&gt;

&lt;p&gt;Let’s move on to the client aspect.&amp;nbsp; First, let’s set up a few things necessary for our client, encapsulated in the Auction module.&amp;nbsp; We’ll set such parameters as our minimum bid, our closing date, our seller and our auction itself.&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:7f1a0be2-d37d-462c-b13a-ce97bffae2d0" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;module&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Auction &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; random &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Random()
  
  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; minBid &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;100&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; closing &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; DateTime.Now.AddMilliseconds &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;10000&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.
  
  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; seller &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; AuctionReply MailboxProcessor(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;fun&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; inbox &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;rec&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; loop() &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
      async { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; _ &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; inbox.Receive() 
              &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; loop()}
    loop())
  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; auction &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; auctionAgent seller minBid closing&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;In order to create a seller for our auction, we need to stub out basic features of this agent.&amp;nbsp; In this case, we simply have a processing loop which receives a message, does nothing with it, and continues with the loop again.&amp;nbsp; As I have stated above, we need both our seller agent, and our auction agent, but what about our clients?&amp;nbsp; In our same module, we define them as the following:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:bb0d6497-1b63-4fe8-bd43-bbc890353b81" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; client i increment top &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; 
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; name &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; sprintf &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;Client %i&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; i
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; log msg &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Console.WriteLine(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;{0}: {1}&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, name, msg)
    
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; AuctionReply MailboxProcessor(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;fun&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; inbox &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
    
      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;rec&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; startAuction() &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
        async { log &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;started&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                auction &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Inquire inbox
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; curMsg &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; inbox.Receive()
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;match&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; curMsg &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;with&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Status(maxBid,_) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                    log &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; sprintf &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;status(%d)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; maxBid
                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; loop &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; maxBid }
      &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;and&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; loop current max &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
        async { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; max &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; top &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;then&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; log &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;too high for me&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                    
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; current&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt; =&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; current &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; max &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;then&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; current&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt; = max + increment&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                    Thread.Sleep (&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;+&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; random.Next &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1000&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
                    auction &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Offer(current&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;, inbox)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                    current&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;else&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; current
                
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; msg &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; inbox.TryReceive timeToShutdown
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;match&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; msg &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;with&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Some BestOffer &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; 
                    log &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; sprintf &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;bestOffer(%d)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; current&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; loop current&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt; max&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Some (BeatenOffer maxBid) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                    log &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; sprintf &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;beatenOffer(%d)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; maxBid
                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; loop current&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;'&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt; maxBid&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Some ( AuctionConcluded(seller, maxBidder) ) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                    log &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;auctionConcluded&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ()
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Some AuctionOver &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                    log &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;auctionOver&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ()
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; None &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; () }
      startAuction())&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;What we’re doing here is having two mutually recursive loops.&amp;nbsp; The first loop, the startAuction loop will get the max bid for us and then go to the main loop where we do our main work.&amp;nbsp; From there, we’ll receive a message sent from the auction to the inbox and determine whether we’re the highest bidder, we’re the maximum or it’s time to call it a day.&amp;nbsp; Once again, fairly straight forward code.&lt;/p&gt;

&lt;p&gt;Lastly, it’s time to bring it all together.&amp;nbsp; Let’s set up the calling code and see the results:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:6bfc795a-9688-4940-bd0e-1cd7c9203547" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;open&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Auction

seller.Start()
auction.Start()
(client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;20&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;200&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;).Start()
(client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;10&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;300&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;).Start()
Console.ReadLine() &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ignore&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Executing this code gives us the following for our results:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:fc4eacbc-fcde-4667-b5b6-91673e86b3bb" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: started
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: started
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: status(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;90&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: status(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;90&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: bestOffer(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;100&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: bestOffer(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;110&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: beatenOffer(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;110&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: beatenOffer(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;120&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: bestOffer(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;120&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: auctionConcluded
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: auctionOver&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;What this tells us is that client 2 starts first and bids first.&amp;nbsp; Client 2 then bids 100, only to be outdone by client 1 and goes back and forth until client 2 comes in with the best and final offer.&amp;nbsp; The auction is then concluded and client 1 is notified that the auction is over.&amp;nbsp; We can add additional client agents to the list and have just as much fun as before.&amp;nbsp; To give you an idea, if we add another agent with an increment of 30 and a max bid of 150, we get the following results:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:dfbbf263-7d55-4678-80d5-e7dad43397a8" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: started
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: started
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;3&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: started
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: status(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;90&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: status(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;90&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;3&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: status(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;90&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: bestOffer(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;110&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: beatenOffer(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;120&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;3&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: bestOffer(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;120&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: beatenOffer(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;120&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;3&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: auctionConcluded
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: auctionOver
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: bestOffer(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;130&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
Client &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;: auctionConcluded&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Now what we have here is that client 2 wins with an offer of 130 and the rest are notified of their loss.&amp;nbsp; You can find the complete code for this example &lt;a href="http://gist.github.com/113912" mce_href="http://gist.github.com/113912"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Solutions such as these using shared-nothing asynchronous message passing can create rather scalable architectures.&amp;nbsp; Utilizing the MailboxProcessor class, we’re able to implement actor model concurrency to tackle some of these problems with coordination of concurrent processes.&amp;nbsp; How might Axum handle this scenario?&amp;nbsp; Good question and I hope to have that answered shortly.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7093288" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Axum/default.aspx">Axum</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Concurrency/default.aspx">Concurrency</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Erlang/default.aspx">Erlang</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/F_2300_/default.aspx">F#</category></item><item><title>Axum – Ping Pong with Dataflow Networks</title><link>http://weblogs.asp.net/podwysocki/archive/2009/05/15/axum-ping-pong-with-dataflow-networks.aspx</link><pubDate>Fri, 15 May 2009 12:48:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7087877</guid><dc:creator>podwysocki</dc:creator><author>podwysocki</author><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/podwysocki/rsscomments.aspx?PostID=7087877</wfw:commentRss><comments>http://weblogs.asp.net/podwysocki/archive/2009/05/15/axum-ping-pong-with-dataflow-networks.aspx#comments</comments><description>&lt;p&gt;&amp;nbsp;&lt;a href="http://codebetter.com/blogs/matthew.podwysocki/archive/2009/05/12/axum-introduction-and-ping-pong-example.aspx" mce_href="http://codebetter.com/blogs/matthew.podwysocki/archive/2009/05/12/axum-introduction-and-ping-pong-example.aspx"&gt;In the previous post&lt;/a&gt;, I gave the canonical Ping-Pong example in &lt;a href="http://msdn.microsoft.com/en-us/devlabs/dd795202.aspx" mce_href="http://msdn.microsoft.com/en-us/devlabs/dd795202.aspx"&gt;Axum&lt;/a&gt; and how it compared with Axum.&amp;nbsp; I want to revisit this post because there are some areas in which we can rework it in addition to the other solutions we’ll visit.&amp;nbsp; Some parts were needlessly chatty and instead we’ll work in some other language features to help clean up our solution.&lt;/p&gt;

&lt;h2&gt;Actors in F#&lt;/h2&gt;

&lt;p&gt;But, before we begin, &lt;a href="http://blogs.msdn.com/concurrently_speaking/" mce_href="http://blogs.msdn.com/concurrently_speaking/"&gt;Nicklas Gustafsson&lt;/a&gt;, the architect behind Axum, was inspired by my post and made an &lt;a href="http://blogs.msdn.com/concurrently_speaking/archive/2009/05/12/actors-in-f.aspx" mce_href="http://blogs.msdn.com/concurrently_speaking/archive/2009/05/12/actors-in-f.aspx"&gt;F# version of the canonical Ping-Pong example&lt;/a&gt;.&amp;nbsp;&amp;nbsp;&amp;nbsp; F# supports a concept of mailbox processing as a first class citizen, much like other languages such as Scala and Erlang, although not as central to the core as it is in Erlang.&lt;/p&gt;

&lt;p&gt;To use these, simply use the MailboxProcessor class.&amp;nbsp; Below is an implementation as given by Nicklas and we can compare with my previous post with the Erlang implementation.&amp;nbsp; The Start function creates a new MailboxProcessor instance and starts it with the given inbox.&amp;nbsp; Much like the Erlang solution, this relies upon recursion as a technique for keeping the mailboxes alive.&amp;nbsp; In order for us to communicate from one mailbox to the other, we must as part of our message, include a reference to our mailbox of origin in order to communicate.&amp;nbsp; &lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:a6548259-f4c3-4ab5-91b6-1a48ca315188" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;#light&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;

&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;type&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Message &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Finished &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Msg &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;of&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; int &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;*&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Message MailboxProcessor

&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ping iters (outbox : Message MailboxProcessor) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
    MailboxProcessor.Start(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;fun&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; inbox &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; 
        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;rec&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; loop n &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; async { 
            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;match&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; n &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;with&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; outbox.Post Finished
                   printfn &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;ping finished&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                   &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ()
            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; _ &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; outbox.Post &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Msg(n, inbox)
                   &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; msg &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; inbox.Receive()
                   printfn &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;ping received pong&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                   &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; loop(n&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;-&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)}
        loop iters)
            
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; pong() &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
    MailboxProcessor.Start(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;fun&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; inbox &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; 
        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;rec&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; loop () &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; async { 
            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; msg &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; inbox.Receive()
            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;match&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; msg &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;with&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Finished &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; 
                printfn &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;pong finished&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ()
            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Msg(n, outbox) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; 
                printfn &lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;pong received ping&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
                outbox.Post &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Msg(n, inbox)
                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; loop() }
                    
        loop())

ping &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;100&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;|&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; pong() &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ignore
System.Console.ReadLine() &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;|&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ignore&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;It’s a fairly straight forward and follows the mold of Erlang quite nicely.&amp;nbsp; Scala as well also follows this mold in &lt;a href="http://www.scala-lang.org/node/242" mce_href="http://www.scala-lang.org/node/242"&gt;their Ping-Pong example&lt;/a&gt;.&amp;nbsp; Using the &lt;a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/actor" mce_href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/actor"&gt;actor package&lt;/a&gt; in Haskell, we can also simulate the &lt;a href="http://gist.github.com/111482" mce_href="http://gist.github.com/111482"&gt;Ping-Pong example&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Of the criticisms mentioned in the post, I have no real issues with these such as the issues with no clear endpoints and how to distinguish the actors from one another.&amp;nbsp; The type safety of Axum does give us some advantages as to define an explicit contract between actors.&lt;/p&gt;

&lt;p&gt;Getting back to the issue at hand, what could we do to clean up our example in Axum?&lt;/p&gt;

&lt;h2&gt;Cleaning Up with Dataflow Networks&lt;/h2&gt;

&lt;p&gt;In our previous example, where we had the two agents communicating with each other, the Ping and the Pong, we pretty much driven by the data received from other agents.&amp;nbsp; Instead, we can turn our attention to using dataflow networks, which is to be driven only by the availability of data entering our network and the computations that are performed as we move through this network.&lt;/p&gt;

&lt;p&gt;Using Axum, we have several operators that can help us.&amp;nbsp; The Forward Operator ( ==&amp;gt; ) sends each message produced by the source to the target.&amp;nbsp; We also have the Forward Once ( –&amp;gt; ) operator which forwards a message from the source to the target, then disconnects after the first message.&amp;nbsp; Using these operators, we can build pretty rich pipelines for our data to flow, but just as well, we could use it to build an event-driven system where we respond to events.&lt;/p&gt;

&lt;p&gt;Let’s take a look at the rewrite of the main agent in which we create the endpoints for Ping and then send the message on the HowMany port.&amp;nbsp; After that, we then forward the received value of Done to the Done state.&amp;nbsp; Much cleaner than before.&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:ffecc17d-f0c9-46fc-98e7-0c886d0659dc" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; System;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; System.Concurrency;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Microsoft.Axum;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; System.Concurrency.Messaging;

&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;agent&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Program : &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;channel&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Application
{
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Program()
    {
        &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Create instance of ping and send msg&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; chan &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Ping.CreateInNewDomain();
        chan::HowMany &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;10&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;
        chan::Done &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;==&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Done;
    }
}&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Next up, let’s take a look at the Ping agent.&amp;nbsp; You’ll note no change in our PingPongStatus channel and the associated ports.&amp;nbsp; The interesting part is in the Ping constructor in which we forward the message from the HowMany port to the Process method which takes the number of iterations to perform.&amp;nbsp; In Process method, we create the Pong instance and communication channels, then we loop through our number of iterations to send the Signal to the Ping port, and receive the return Signal on the Pong port.&amp;nbsp; After the loop, we send a message to the Done to close the interaction and then return a Signal to end our Ping.&amp;nbsp; Below is the implementation of the code.&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:20b73a32-a8cf-401f-811a-558ff64feccd" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;channel&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; PingPongStatus
{
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;input&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; HowMany : Signal;
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;output&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Signal Done;
    Start: { HowMany &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; End; }
}

&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;agent&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Ping : &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;channel&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; PingPongStatus
{
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Ping()
    {
        PrimaryChannel::HowMany &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;==&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Process;
    }
   
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Signal Process(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; iters)
    {
        &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Create pong&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; chan &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Pong.CreateInNewDomain();      
        
        &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Send pings and receive pongs&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;for&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; i &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;; i &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; iters; i&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;++&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
        {
            chan::Ping &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Signal.Value;
            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;receive&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(chan::Pong);
            Console.WriteLine(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;ping received pong&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);
        }
        chan::Done &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Signal.Value;
        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Signal.Value;
    }  
}&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;You’ll notice that we’re no longer interested in sending the number of iterations to the Pong.&amp;nbsp; It shouldn’t be needed and instead, we can send the Signal message on the Done port when we’re complete.&amp;nbsp; The Pong can listen in an infinite loop until it receives the message on the Done port.&lt;/p&gt;

&lt;p&gt;Lastly, let’s take a look at the Pong agent.&amp;nbsp; We’ll clean up the channel to rid ourselves of the HowMany port.&amp;nbsp; Instead, all we need are Signals to communicate at this point inside the infinite loop that I mentioned above.&amp;nbsp; Let’s take a look at the code required.&amp;nbsp; &lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:8cdd4273-10cf-43f3-9dd9-d261ddc6ae76" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;channel&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; PingPong
{
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;input&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Signal Done;
    
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;input&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Signal Ping;
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;output&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Signal Pong;
}

&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;agent&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Pong : &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;channel&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; PingPong
{
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Pong()
    {
        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;while&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;receive&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
        {
          &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;from&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; PrimaryChannel::Done:
            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;
          &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;from&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; PrimaryChannel::Ping: 
            Console.WriteLine(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;pong received ping&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);
            PrimaryChannel::Pong &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;--&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Signal.Value;
            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;break&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;    
        }
    }
}&lt;/span&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;As you can see, inside the Pong constructor, we’re performing an infinite loop in which we call receive each time, then we can react to the messages coming on the specified ports, in this case, the Done and the Ping ports.&amp;nbsp; If we receive a message on the Ping port, we then send a Signal back on the Pong port and then break.&amp;nbsp; Else, if we receive a message on the Done port, then we exit the agent.&amp;nbsp; This approach is a bit more cleaner than our previous attempt at the Ping-Pong example.&amp;nbsp; &lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;As I indicated before, are other angles I wish to tackle with this example, including using asynchronous methods, ordered interaction points and so on, which I will get into in subsequent posts.&amp;nbsp; With this little cleanup, I hope this shows some of the power of the language that we can indeed create concise, yet safe concurrent apps using message passing.&amp;nbsp; &lt;a href="http://msdn.microsoft.com/en-us/devlabs/dd795202.aspx" mce_href="http://msdn.microsoft.com/en-us/devlabs/dd795202.aspx"&gt;Download it&lt;/a&gt;, use it in anger, and give the team &lt;a href="http://social.msdn.microsoft.com/Forums/en/axum." mce_href="http://social.msdn.microsoft.com/Forums/en/axum."&gt;feedback on the MSDN forum&lt;/a&gt;.&amp;nbsp; Once again, with your help we can help shape the future of an actor based concurrency model on .NET.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7087877" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Axum/default.aspx">Axum</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Concurrency/default.aspx">Concurrency</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Erlang/default.aspx">Erlang</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Haskell/default.aspx">Haskell</category></item><item><title>Talking Functional Programming with Erik Meijer</title><link>http://weblogs.asp.net/podwysocki/archive/2009/03/25/talking-functional-programming-with-erik-meijer.aspx</link><pubDate>Wed, 25 Mar 2009 04:58:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6998274</guid><dc:creator>podwysocki</dc:creator><author>podwysocki</author><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/podwysocki/rsscomments.aspx?PostID=6998274</wfw:commentRss><comments>http://weblogs.asp.net/podwysocki/archive/2009/03/25/talking-functional-programming-with-erik-meijer.aspx#comments</comments><description>&lt;p&gt;When I was last out in Redmond, I had the opportunity to sit down with Erik Meijer to speak about something for which I’m passionate, functional programming.&amp;nbsp; After such recent appearances on Channel9 as &lt;a href="http://channel9.msdn.com/shows/Going+Deep/Joe-Duffy-Perspectives-on-Concurrent-Programming-and-Parallelism/" mce_href="http://channel9.msdn.com/shows/Going+Deep/Joe-Duffy-Perspectives-on-Concurrent-Programming-and-Parallelism/"&gt;Joe Duffy&lt;/a&gt; and &lt;a href="http://channel9.msdn.com/shows/Going+Deep/Expert-to-Expert-Anders-Hejlsberg-The-Future-of-C/" mce_href="http://channel9.msdn.com/shows/Going+Deep/Expert-to-Expert-Anders-Hejlsberg-The-Future-of-C/"&gt;Anders Hejlsberg&lt;/a&gt;, I was quite flattered to be asked to appear.&amp;nbsp; I gave a short as possible introduction to start talking about any number of topics including my passion for functional programming, the Haskell and F# languages, and many other ideas.&lt;/p&gt;

&lt;p&gt;One of the topics I talked about was monads.&amp;nbsp; In some of my previous posts, I talked about them extensively in my &lt;a href="http://codebetter.com/blogs/matthew.podwysocki/archive/2009/02/20/much-ado-about-monads-list-edition.aspx" mce_href="http://codebetter.com/blogs/matthew.podwysocki/archive/2009/02/20/much-ado-about-monads-list-edition.aspx"&gt;Much Ado About Monads&lt;/a&gt; series.&amp;nbsp; When I got the email that this video was posted, I was already writing my series installment on the asynchronous monad, so I hope this video will serve as a fine addition to that conversation when I get finished with it later this week.&lt;/p&gt;

&lt;p&gt;So without further ado, here is the &lt;a href="http://channel9.msdn.com/shows/Going+Deep/Erik-Meijer-and-Matthew-Podwysocki-Perspectives-on-Functional-Programming/" mce_href="http://channel9.msdn.com/shows/Going+Deep/Erik-Meijer-and-Matthew-Podwysocki-Perspectives-on-Functional-Programming/"&gt;video&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6998274" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Concurrency/default.aspx">Concurrency</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Functional+Programming/default.aspx">Functional Programming</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Haskell/default.aspx">Haskell</category></item><item><title>Which Is More Beautiful Architecture - FP or OOP?</title><link>http://weblogs.asp.net/podwysocki/archive/2009/03/09/which-is-more-beautiful-architecture-fp-or-oop.aspx</link><pubDate>Mon, 09 Mar 2009 16:31:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6951647</guid><dc:creator>podwysocki</dc:creator><author>podwysocki</author><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/podwysocki/rsscomments.aspx?PostID=6951647</wfw:commentRss><comments>http://weblogs.asp.net/podwysocki/archive/2009/03/09/which-is-more-beautiful-architecture-fp-or-oop.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://codebetter.com/blogs/matthew.podwysocki/image_00CB5D14.png" mce_href="http://codebetter.com/blogs/matthew.podwysocki/image_00CB5D14.png"&gt;&lt;img src="http://codebetter.com/blogs/matthew.podwysocki/image_thumb_793FEDA6.png" style="display: inline; margin-left: 0px; margin-right: 0px;" alt="image" mce_src="http://codebetter.com/blogs/matthew.podwysocki/image_thumb_793FEDA6.png" align="right" border="0"&gt;&lt;/a&gt; Recently, upon the recommendations of a few people, I picked up a copy of the book “Beautiful Architecture: Leading Thinkers Reveal the Hidden Beauty in Software”.&amp;nbsp; This book is a great read and includes essays from some of the top minds in software today.&amp;nbsp; Some of the topics covered are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;How &lt;a href="http://www.facebook.com/" mce_href="http://www.facebook.com/"&gt;Facebook's&lt;/a&gt; architecture is the basis for a data-centric application ecosystem &lt;/li&gt;

  &lt;li&gt;The effect of &lt;a href="http://www.xen.org/" mce_href="http://www.xen.org/"&gt;Xen's&lt;/a&gt; well-designed architecture on the way operating systems evolve &lt;/li&gt;

  &lt;li&gt;How community processes within the &lt;a href="http://www.kde.org" mce_href="http://www.kde.org"&gt;KDE&lt;/a&gt; project help software architectures evolve from rough sketches to beautiful systems &lt;/li&gt;

  &lt;li&gt;How feature creep has helped &lt;a href="http://www.gnu.org/software/emacs/" mce_href="http://www.gnu.org/software/emacs/"&gt;GNU Emacs&lt;/a&gt; gain unanticipated functionality &lt;/li&gt;

  &lt;li&gt;The magic behind the &lt;a href="http://jikesrvm.org/" mce_href="http://jikesrvm.org/"&gt;Jikes RVM&lt;/a&gt; self-optimizable, self-hosting runtime &lt;/li&gt;

  &lt;li&gt;The design choices and building blocks that made &lt;a href="http://en.wikipedia.org/wiki/Tandem_Computers" mce_href="http://en.wikipedia.org/wiki/Tandem_Computers"&gt;Tandem&lt;/a&gt; the choice platform in high-availability environments for over two decades &lt;/li&gt;

  &lt;li&gt;The differences and similarities between object-oriented and functional architectural views &lt;/li&gt;

  &lt;li&gt;How architectures can affect the software's evolution and the developers' engagement &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But one essay in particular caught my attention was Chapter 13 Software Architecture: Object-Oriented Versus Functional by &lt;a href="http://se.ethz.ch/%7Emeyer/" mce_href="http://se.ethz.ch/~meyer/"&gt;Bertrand Meyer&lt;/a&gt;.&amp;nbsp; In this writing, he steps through an example application of financial contracts, as presented in both a presentation called &lt;a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.493" mce_href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.493"&gt;“Composing contracts: An adventure in financial engineering”&lt;/a&gt; by &lt;a href="http://research.microsoft.com/en-us/people/simonpj/" mce_href="http://research.microsoft.com/en-us/people/simonpj/"&gt;Simon Peyton-Jones&lt;/a&gt;, &lt;a href="http://lexifi.com/" mce_href="http://lexifi.com/"&gt;Jean-Marc Eber&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Julian_Seward" mce_href="http://en.wikipedia.org/wiki/Julian_Seward"&gt;Julian Seward&lt;/a&gt;, along with an associated presentation by Jean-Marc Eber called &lt;a href="http://lexifi.com/Downloads/MLFiPresentation.ppt" mce_href="http://lexifi.com/Downloads/MLFiPresentation.ppt"&gt;“Compositional Description, Valuation, and Management of Financial Contracts:&amp;nbsp; The MLFi Language”.&lt;/a&gt;&amp;nbsp; &lt;/p&gt;

&lt;p&gt;Bertrand Meyer’s overall conclusion is that given the above functional solution, an object-oriented design, especially supporting such features as closures is better than the functional approach as it can provide higher-level abstractions more supportive of extension and reuse.&lt;/p&gt;

&lt;h2&gt;Laying Out The Case&lt;/h2&gt;

&lt;p&gt;Dr. Meyer defines what architecture “beauty” is from his 1997 hallmark book, &lt;a href="http://archive.eiffel.com/doc/oosc/page.html" mce_href="http://archive.eiffel.com/doc/oosc/page.html"&gt;“Object-Oriented Software Construction, Second Edition”&lt;/a&gt; as three objective criteria:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;Reliability&lt;/b&gt; 

    &lt;br&gt;Does the architecture help establish the correctness and robustness of the software? 

    &lt;br&gt;&lt;/li&gt;

  &lt;li&gt;&lt;b&gt;Extendibility&lt;/b&gt; 

    &lt;br&gt;How easy is it to accommodate change? 

    &lt;br&gt;&lt;/li&gt;

  &lt;li&gt;&lt;b&gt;Reusability&lt;/b&gt; 

    &lt;br&gt;Is the solution general, or better yet, can we turn it into a component to be plugged in directly, off-the-shelf, into a new application? &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using the above criteria and the functional examples cited, there are a few issues as noted with his essay such as the lack of data points, lack of detail, and a specific focus on modularity, whereas the functional programming examples had a focus on other criteria such as elegance of a declarative approach.&amp;nbsp; The biggest drawback to this essay is that most, if not all Object Oriented examples revolve around the use of Eiffel, which is a fringe language and not in the mainstream thought in the Object Oriented world.&amp;nbsp; To focus on this versus a mainstream functional language such as Haskell has some serious drawbacks that I don’t think can be reconciled in this essay.&lt;/p&gt;

&lt;p&gt;Now, I’m not going to go through the example as I linked them above for you to dissect at your leisure.&amp;nbsp;&amp;nbsp;&amp;nbsp; Instead, we’re going to focus on the single issue of modularity between the two approaches.&lt;/p&gt;

&lt;h2&gt;Extendibility/Reusability&lt;/h2&gt;

&lt;p&gt;To speak to the reuse and extendibility issue, the functional example is heavy in the use of combinators, which are functions that take functions as arguments and return new functions.&amp;nbsp; The idea is that the financial world has a lot of jargon and instead of specifying a large set of contracts ahead of time, we could compose them using a strict set of combinators.&amp;nbsp; This way, we have the ability to define new unforeseen financial contracts with relative ease in a declarative manner.&amp;nbsp; The paper is quite compelling for how to build composable Domain Specific Languages around financial modeling, for which functional programming is widely used.&lt;/p&gt;

&lt;p&gt;To the author the idea of defining combinators does not scale to large applications and must be divided into modules.&amp;nbsp; In turn, the extendibility problem arises on how you modularize said code while affecting the fewest modules possible.&amp;nbsp; Another issue is that with a one module approach, this does not help reusability as you wish to have only a subset of those operations imported.&amp;nbsp; Careful modularization can get around these issues and I do not necessarily see this as a stumbling block.&amp;nbsp; Instead with a good strategy on modularization and qualifying imports can solve a lot of these issues.&amp;nbsp; Also, the use of type classes can add extendibility to your architecture by defining a set of operations in which other types can &lt;/p&gt;

&lt;h2&gt;Managing State&lt;/h2&gt;

&lt;p&gt;Another issue raised by the author is state management.&amp;nbsp; The notion of stateless programming is essential to the pure functional programmer.&amp;nbsp; State and unmanaged side effects are indeed the bane of concurrency.&amp;nbsp; Instead, Haskell has the notion of monads which allow for the modeling of not only state, but exception management, as well as input/output operations.&lt;/p&gt;

&lt;p&gt;Dr. Meyer doesn’t have a concern about the whether these concepts are hard to learn, as they shouldn’t be, but instead, if they are worth the effort at all.&amp;nbsp; Instead, through the use of Command Query Separation, where queries return results but do not alter the world, whereas commands alter the state of the world and do not return a value.&amp;nbsp; I believe, to rely on this design pattern instead of enforcement through the type system is his undoing.&amp;nbsp; Most imperative/object-oriented programmers do not follow this rule and thus should only confine his comments to Eiffel alone.&amp;nbsp; I believe once again, his focus on Eiffel is undercutting his credibility that well known OOP principles can subsume a Functional Programming example.&lt;/p&gt;

&lt;p&gt;This analysis could go on and on, but must this be an either/or battle?&lt;/p&gt;

&lt;h2&gt;The False Battle&lt;/h2&gt;

&lt;p&gt;With the exclusion of Java, most modern languages have been evolving to include such concepts as closures, which come from the functional world.&amp;nbsp; Even the Eiffel language that has been written by the author, has incorporated “agents” which are his term for closures.&amp;nbsp; And then we have multi-paradigm languages such as F# and Scala which take more of a functional programming approach with the full support of imperative and object oriented features.&lt;/p&gt;

&lt;p&gt;Although at this point in history, functional programming languages are less popular in mainstream development, it’s hard to now avoid their influence.&amp;nbsp; With the increased attention to concurrency and parallelism, the ideas from functional programming such as lack of state and immutability are gaining momentum as we realize the peril of shared state.&amp;nbsp; Instead of this battle, where can object oriented technologies learn from functional programming and vice versa?&lt;/p&gt;

&lt;h2&gt;How Functional Programming Influences&lt;/h2&gt;

&lt;p&gt;Let’s try another tactic with this and talk about where functional programming techniques have their biggest influence.&amp;nbsp; &lt;a href="http://lorgonblog.spaces.live.com/" mce_href="http://lorgonblog.spaces.live.com/"&gt;Brian McNamara&lt;/a&gt;, of the F# team, laid out the argument well in his post &lt;a href="http://lorgonblog.spaces.live.com/Blog/cns%21701679AD17B6D310%21511.entry" mce_href="http://lorgonblog.spaces.live.com/Blog/cns!701679AD17B6D310!511.entry"&gt;“How does functional programming affect the structure of your code”&lt;/a&gt; in which he describes its effects in three distinct areas:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;b&gt;In the Large&lt;/b&gt; 

    &lt;br&gt;Covers overall architecture and high level design.&amp;nbsp; This is where the modularization of our code has its biggest influences.&amp;nbsp; To instill laziness as a default architecture, compose message passing systems and high performance computing concerns is where functional programming can have its greatest impact. 

    &lt;br&gt;&lt;/li&gt;

  &lt;li&gt;&lt;b&gt;In the Medium&lt;/b&gt; 

    &lt;br&gt;The medium covers more lower level API decisions that we make.&amp;nbsp; When combined with a good modularization strategy, can yield great results.&amp;nbsp; Many times as well the object oriented design patterns such as the command, builder, strategy and visitor patterns can better be expressed through functions.&amp;nbsp; &lt;br&gt;Also, the use of discriminated unions, records and collection structures can create concise and rich domain models using pure functional structures. 

    &lt;br&gt;&lt;/li&gt;

  &lt;li&gt;&lt;b&gt;In the Small 
      &lt;br&gt;&lt;/b&gt;By programming in the small, we mean at the actual function level.&amp;nbsp; With an immutable by default posture, we are better able to express our values without type annotations and the compiler is better able to make decisions based upon that.&amp;nbsp; Functional composition is also very much in effect at this level as we build more powerful functions from the small pieces to create rich solutions. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By understanding these concepts help us better understand where functional programming has its greatest influence and where we can use the techniques even if not in a pure functional language.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Overall, the arguments presented by Bertrand Meyer were persuasive in some ways, yet lacking in others.&amp;nbsp; Unable to cite more real world applications leaves me wanting.&amp;nbsp; Without this, the modularization issue cannot be addressed in full.&amp;nbsp; Other areas such as insisting on Command-Query-Separation as a default falls largely on deaf ears outside of the Eiffel community.&amp;nbsp; I do realize the more progressive teachers are starting to focus on this, but for the most part, CQS is largely untaught.&amp;nbsp; Instead having the type system express our side effects is a much more powerful option.&amp;nbsp; Overall, I thought a lot of the arguments given his bias and the lack of better examples, fell flat.&amp;nbsp; Using Eiffel, a non-mainstream OOP langauge doesn’t help his case and should have focused on more mainstream approaches as in C#, and Ruby among others.&lt;/p&gt;

&lt;p&gt;So, who wins?&amp;nbsp; That’s a good question.&amp;nbsp; If you’re in a world resigned to side effects then OOP might just be for you.&amp;nbsp; Else, Haskell and the lessons learned from the language can be powerful instruments in creating rich and beautiful architectures using pure functional techniques.&amp;nbsp; I feel with time and maturation, the functional programming community can contribute more to the architecture picture.&amp;nbsp; The battle continues?&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6951647" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/podwysocki/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Concurrency/default.aspx">Concurrency</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Functional+Programming/default.aspx">Functional Programming</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/OOP/default.aspx">OOP</category></item><item><title>Exploring MapReduce with F#</title><link>http://weblogs.asp.net/podwysocki/archive/2009/03/03/exploring-mapreduce-with-f.aspx</link><pubDate>Tue, 03 Mar 2009 07:09:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6935989</guid><dc:creator>podwysocki</dc:creator><author>podwysocki</author><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/podwysocki/rsscomments.aspx?PostID=6935989</wfw:commentRss><comments>http://weblogs.asp.net/podwysocki/archive/2009/03/03/exploring-mapreduce-with-f.aspx#comments</comments><description>&lt;p&gt;With my exploration into mass concurrency and big data problems, I’m always finding challenges to give myself on how I might solve a given issue.&amp;nbsp; Such examples that have intrigued me along the way as &lt;a href="http://msdn.microsoft.com/en-us/concurrency/default.aspx" mce_href="http://msdn.microsoft.com/en-us/concurrency/default.aspx"&gt;PLINQ&lt;/a&gt;, &lt;a href="http://www.osl.iu.edu/research/mpi.net/" mce_href="http://www.osl.iu.edu/research/mpi.net/"&gt;MPI/.NET&lt;/a&gt;, &lt;a href="http://haskell.org/haskellwiki/GHC/Data_Parallel_Haskell" mce_href="http://haskell.org/haskellwiki/GHC/Data_Parallel_Haskell"&gt;Data Parallel Haskell&lt;/a&gt;, but one in particular has intrigued me more – &lt;a href="http://labs.google.com/papers/mapreduce.html" mce_href="http://labs.google.com/papers/mapreduce.html"&gt;MapReduce&lt;/a&gt;.&amp;nbsp; A challenge I gave myself is to fully understand this paradigm and implement a version using F#.&lt;/p&gt;

&lt;h3&gt;What Is MapReduce?&lt;/h3&gt;

&lt;p&gt;MapReduce is a Google programming model and implementation for processing and generating large data sets.&amp;nbsp; Programs written using this more functional style can be parallelized over a large cluster of machines without needing the knowledge of concurrent programming.&amp;nbsp; The actual runtime can then partition the data, schedule and handle any potential failure.&amp;nbsp; The Google implementation of it runs on a large cluster of machines and can process terabytes of data at a time.&amp;nbsp; &lt;/p&gt;

&lt;p&gt;The programming model is based upon five simple concepts:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Iteration over input&lt;/li&gt;

  &lt;li&gt;Computation of key/value pairs from each input&lt;/li&gt;

  &lt;li&gt;Grouping of all intermediate values by key&lt;/li&gt;

  &lt;li&gt;Iteration over the resulting groups&lt;/li&gt;

  &lt;li&gt;Reduction of each group&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, where does this Map/Reduce wording come in?&amp;nbsp; Well, let’s explore each:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Map&lt;/strong&gt;

    &lt;br&gt;Function written by the user to take an input pair and produce a result of intermediate key/value pairs.&amp;nbsp; The intermediate values are then grouped with the same intermediate key and passed to the Reduce function.

    &lt;br&gt;&lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;Reduce&lt;/strong&gt;

    &lt;br&gt;Function also written by the user to take the intermediate key and sequence of values for that key.&amp;nbsp; The sequence of values are then merged to produce a possibly smaller set of values.&amp;nbsp; Zero or one output value is produced per our Reduce function invocation.&amp;nbsp; In order to manage memory, an iterator is used for potentially large data sets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How useful is this programming model?&amp;nbsp; Using this model, we’re able to express some interesting problems such as the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Word counts in large documents&lt;/li&gt;

  &lt;li&gt;Distributed Grep – Find patterns in a document&lt;/li&gt;

  &lt;li&gt;Count of URL Access Frequency &lt;/li&gt;

  &lt;li&gt;Reverse Web-Link Graph – Find all source URLs for a given destination&lt;/li&gt;

  &lt;li&gt;Term-Vector per Host - Summarize most important words in a document&lt;/li&gt;

  &lt;li&gt;Inverted Index&lt;/li&gt;

  &lt;li&gt;Distributed Sort&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s only a start to what we can do.&amp;nbsp; After the paper which explained the technology was published in 2004, there have been several implementations including the open-source &lt;a href="http://hadoop.apache.org/core/" mce_href="http://hadoop.apache.org/core/"&gt;Hadoop project&lt;/a&gt; and the &lt;a href="http://research.microsoft.com/en-us/projects/Dryad/" mce_href="http://research.microsoft.com/en-us/projects/Dryad/"&gt;Microsoft Research Project Dryad&lt;/a&gt;.&amp;nbsp; Of course, it doesn’t come without some criticism about the resource usage such as this post called &lt;a href="http://www.dbms2.com/2008/10/15/ebay-doesnt-love-mapreduce/" mce_href="http://www.dbms2.com/2008/10/15/ebay-doesnt-love-mapreduce/"&gt;“eBay doesn’t love MapReduce”&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Dryad is more interesting in that its functionality subsumes MapReduce and can do in regards to job creation, resource management, job monitoring, visualization and more.&amp;nbsp; What’s even more interesting is the associated project &lt;a href="http://research.microsoft.com/en-us/projects/dryadlinq/default.aspx" mce_href="http://research.microsoft.com/en-us/projects/dryadlinq/default.aspx"&gt;DryadLINQ&lt;/a&gt;, which allows us to compile LINQ expressions to have sent across the cluster so that I could perform intense data analysis using LINQ operators that we’re used for our other data tasks.&amp;nbsp; What does the future hold for Dryad remains to be seen, but the possibilities seem plenty.&lt;/p&gt;

&lt;h2&gt;F# Implementation&lt;/h2&gt;

&lt;p&gt;The challenge I gave myself was to understand the basics of the programming model.&amp;nbsp; Ralf Lämmel, formerly of the Microsoft Programmability Team, published a paper entitled &lt;a href="http://www.cs.vu.nl/%7Eralf/MapReduce/paper.pdf" mce_href="http://www.cs.vu.nl/~ralf/MapReduce/paper.pdf"&gt;Google’s MapReduce Programming Model – Revisited&lt;/a&gt; which I used as a source for how my F# implementation works.&amp;nbsp; If you want to understand not only the deep internal details, but also how an implementation in Haskell would look, I highly recommend this paper.&lt;/p&gt;

&lt;p&gt;In our example, we’re going to use a MapReduce implementation to look for the most frequent IP addresses from our IIS logs.&amp;nbsp; Let’s first start by defining the outer skeleton needed.&amp;nbsp; Let’s define what the map_reduce function and associated steps will look like:&lt;/p&gt;

&lt;div style="font-family: courier new;"&gt;&lt;span style="color: blue;"&gt;#light&lt;/span&gt;&amp;nbsp; &lt;br&gt;

  &lt;br&gt;&lt;span style="color: blue;"&gt;namespace&lt;/span&gt; CodeBetter&lt;span style="color: blue;"&gt;.&lt;/span&gt;MapReduceExample&amp;nbsp; &lt;br&gt;

  &lt;br&gt;&lt;span style="color: blue;"&gt;module&lt;/span&gt; MapReduceModule =&amp;nbsp; &lt;br&gt;

  &lt;br&gt;&amp;nbsp; &lt;span style="color: blue;"&gt;let&lt;/span&gt; map_reduce&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Map function take pair and create sequence of key/value pairs &lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;(&lt;/span&gt;m&lt;span style="color: blue;"&gt;:&lt;/span&gt;'k1 &lt;span style="color: blue;"&gt;-&amp;gt;&lt;/span&gt; 'v1 &lt;span style="color: blue;"&gt;-&amp;gt;&lt;/span&gt; seq&amp;lt;'k2 * 'v2&amp;gt;&lt;span style="color: blue;"&gt;)&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Reduce function takes key and sequence to produce optional value &lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;(&lt;/span&gt;r&lt;span style="color: blue;"&gt;:&lt;/span&gt;'k2 &lt;span style="color: blue;"&gt;-&amp;gt;&lt;/span&gt; seq&amp;lt;'v2&amp;gt; &lt;span style="color: blue;"&gt;-&amp;gt;&lt;/span&gt; 'v3 option&lt;span style="color: blue;"&gt;)&lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Takes an input of key/value pairs to produce an output key/value pairs&lt;/span&gt;

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;:&lt;/span&gt; Map&amp;lt;'k1, 'v1&amp;gt; &lt;span style="color: blue;"&gt;-&amp;gt;&lt;/span&gt; Map&amp;lt;'k2, 'v3&amp;gt; =&amp;nbsp; &lt;br&gt;

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; map_per_key &amp;gt;&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// 1. Apply map function to each key/value pair &lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; group_by_key &amp;gt;&amp;gt;&amp;nbsp; &lt;span style="color: green;"&gt;// 2. Group intermediate data per key &lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; reduce_per_key&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// 3. Apply reduce to each group &lt;/span&gt;&lt;/div&gt;

&lt;p&gt;I’m using the standard sequences instead of lists for this because the data may be large and the List&amp;lt;T&amp;gt; in F# by default is eagerly evaluated.&amp;nbsp; The case could be made to use the LazyList&amp;lt;T&amp;gt; to model the data, but as I might want to use the Parallel Extensions and the PSeq module I used before, I’ll stick with the IEnumerable&amp;lt;T&amp;gt;.&lt;/p&gt;

&lt;p&gt;The comments here in the code say a lot about what’s going on.&amp;nbsp; Our map_reduce function takes two functions, the map and the reduce which are explained in the code comments.&amp;nbsp; It’s important to understand what happens last is our series of three functions, our map_per_key, group_by_key and reduce_per_key.&amp;nbsp; Each of those steps fall into line with the explanation from above.&amp;nbsp; At this point, we haven’t actually yet implemented the functions, but let’s go ahead and do that now to flush out our map_per_key, group_by_key and reduce_per_key.&amp;nbsp; The following code comes before the last statement which ties our three functions together:&lt;/p&gt;

&lt;div style="font-family: courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;let&lt;/span&gt; map_per_key &lt;span style="color: blue;"&gt;:&lt;/span&gt; Map&amp;lt;'k1, 'v1&amp;gt; &lt;span style="color: blue;"&gt;-&amp;gt;&lt;/span&gt; seq&amp;lt;&lt;span style="color: blue;"&gt;(&lt;/span&gt;'k2 * 'v2&lt;span style="color: blue;"&gt;)&lt;/span&gt;&amp;gt; = 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Map&lt;span style="color: blue;"&gt;.&lt;/span&gt;to_seq &amp;gt;&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// 1. Map into a sequence&lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Seq&lt;span style="color: blue;"&gt;.&lt;/span&gt;map &lt;span style="color: blue;"&gt;(&lt;/span&gt;Tuple&lt;span style="color: blue;"&gt;.&lt;/span&gt;uncurry m&lt;span style="color: blue;"&gt;)&lt;/span&gt; &amp;gt;&amp;gt;&amp;nbsp; &lt;span style="color: green;"&gt;// 2. Map m over a list of pairs&lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Seq&lt;span style="color: blue;"&gt;.&lt;/span&gt;concat&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// 3. Concat per-key lists&lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;let&lt;/span&gt; group_by_key &lt;span style="color: blue;"&gt;(&lt;/span&gt;l&lt;span style="color: blue;"&gt;:&lt;/span&gt;seq&amp;lt;&lt;span style="color: blue;"&gt;(&lt;/span&gt;'k2 * 'v2&lt;span style="color: blue;"&gt;)&lt;/span&gt;&amp;gt;&lt;span style="color: blue;"&gt;)&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;:&lt;/span&gt; Map&amp;lt;'k2,seq&amp;lt;'v2&amp;gt;&amp;gt; = 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;let&lt;/span&gt; insert d &lt;span style="color: blue;"&gt;(&lt;/span&gt;k2, v2&lt;span style="color: blue;"&gt;)&lt;/span&gt; = Map&lt;span style="color: blue;"&gt;.&lt;/span&gt;insert_with Seq&lt;span style="color: blue;"&gt;.&lt;/span&gt;append k2 &lt;span style="color: blue;"&gt;(&lt;/span&gt;seq &lt;span style="color: blue;"&gt;[&lt;/span&gt;v2&lt;span style="color: blue;"&gt;]&lt;/span&gt;&lt;span style="color: blue;"&gt;)&lt;/span&gt; d 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;let&lt;/span&gt; func &lt;span style="color: blue;"&gt;(&lt;/span&gt;f&lt;span style="color: blue;"&gt;:&lt;/span&gt;Map&amp;lt;'a, seq&amp;lt;'b&amp;gt;&amp;gt; &lt;span style="color: blue;"&gt;-&amp;gt;&lt;/span&gt; Map&amp;lt;'a, seq&amp;lt;'b&amp;gt;&amp;gt;&lt;span style="color: blue;"&gt;)&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;(&lt;/span&gt;c&lt;span style="color: blue;"&gt;:&lt;/span&gt;'a * 'b&lt;span style="color: blue;"&gt;)&lt;/span&gt;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;:&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;(&lt;/span&gt;Map&amp;lt;'a, seq&amp;lt;'b&amp;gt;&amp;gt; &lt;span style="color: blue;"&gt;-&amp;gt;&lt;/span&gt; Map&amp;lt;'a, seq&amp;lt;'b&amp;gt;&amp;gt;&lt;span style="color: blue;"&gt;)&lt;/span&gt; =&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;fun&lt;/span&gt; x &lt;span style="color: blue;"&gt;-&amp;gt;&lt;/span&gt; f&lt;span style="color: blue;"&gt;(&lt;/span&gt;insert x c&lt;span style="color: blue;"&gt;)&lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;(&lt;/span&gt;Seq&lt;span style="color: blue;"&gt;.&lt;/span&gt;fold func &lt;span style="color: blue;"&gt;(&lt;/span&gt;&lt;span style="color: blue;"&gt;fun&lt;/span&gt; x &lt;span style="color: blue;"&gt;-&amp;gt;&lt;/span&gt; x&lt;span style="color: blue;"&gt;)&lt;/span&gt; l&lt;span style="color: blue;"&gt;)&lt;/span&gt; Map&lt;span style="color: blue;"&gt;.&lt;/span&gt;empty 

  &lt;br&gt;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;let&lt;/span&gt; reduce_per_key &lt;span style="color: blue;"&gt;:&lt;/span&gt; Map&amp;lt;'k2, seq&amp;lt;'v2&amp;gt;&amp;gt; &lt;span style="color: blue;"&gt;-&amp;gt;&lt;/span&gt; Map&amp;lt;'k2,'v3&amp;gt; = 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;let&lt;/span&gt; un_some k &lt;span style="color: blue;"&gt;(&lt;/span&gt;Some v&lt;span style="color: blue;"&gt;)&lt;/span&gt; = v &lt;span style="color: green;"&gt;// Remove optional type&lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;let&lt;/span&gt; is_some k = &lt;span style="color: blue;"&gt;function&lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;|&lt;/span&gt; Some _ &lt;span style="color: blue;"&gt;-&amp;gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;true&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Keep entires&lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;|&lt;/span&gt; None&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;-&amp;gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;false&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Remove entries&lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Map&lt;span style="color: blue;"&gt;.&lt;/span&gt;mapi r &amp;gt;&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// 1. Apply reduce per key&lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Map&lt;span style="color: blue;"&gt;.&lt;/span&gt;filter is_some &amp;gt;&amp;gt; &lt;span style="color: green;"&gt;// 2. Remove None entries&lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Map&lt;span style="color: blue;"&gt;.&lt;/span&gt;mapi un_some&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// 3. Transform to remove option&lt;/span&gt;&lt;/div&gt;

&lt;div style="font-family: courier new;"&gt;&lt;span style="color: green;"&gt;&lt;/span&gt;&lt;/div&gt;
The first function is the map_per_key which first turns a map into a sequence.&amp;nbsp; Then we map the m function over our list of pairs, and then finally concat the per-key lists.&amp;nbsp; Next our group by key might look a little interesting, but it’s simply a right fold over our insert function and our sequence of key/value pairs.&amp;nbsp; As I had in a previous post about how you can do right-folds in the terms of a left-fold.&amp;nbsp; Finally, our reduce per key applies the reduce function, then filters the removable entries, and finally transforms to remove the optional type.

&lt;p&gt;There you have it, our implementation of a MapReduce.&amp;nbsp; Now let’s step ahead with our implementation to step through our IIS logs.&amp;nbsp; Let’s first retrieve the data for our logs from a given directory.&amp;nbsp; We can use the async workflows in F# to retrieve this data in parallel given a base directory.&amp;nbsp; Next, we need a way to harvest the data from the given logs so that we can get the IP address from it.&lt;/p&gt;

&lt;div style="font-family: courier new;"&gt;&lt;span style="color: blue;"&gt;module&lt;/span&gt; LogCount = 

  &lt;br&gt;&amp;nbsp; &lt;span style="color: blue;"&gt;open&lt;/span&gt; System&lt;span style="color: blue;"&gt;.&lt;/span&gt;IO 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp; &lt;span style="color: blue;"&gt;let&lt;/span&gt; processed_logs &lt;span style="color: blue;"&gt;:&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;(&lt;/span&gt;&lt;span style="color: blue;"&gt;string&lt;/span&gt; * &lt;span style="color: blue;"&gt;string&lt;/span&gt;&lt;span style="color: blue;"&gt;)&lt;/span&gt; array =&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Async&lt;span style="color: blue;"&gt;.&lt;/span&gt;Run &lt;span style="color: blue;"&gt;(&lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Async&lt;span style="color: blue;"&gt;.&lt;/span&gt;Parallel&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;[&lt;/span&gt;&lt;span style="color: blue;"&gt;for&lt;/span&gt; file &lt;span style="color: blue;"&gt;in&lt;/span&gt; Directory&lt;span style="color: blue;"&gt;.&lt;/span&gt;GetFiles &lt;span style="color: maroon;"&gt;@"C:\Logs\"&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;-&amp;gt;&lt;/span&gt;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; async &lt;span style="color: blue;"&gt;{&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;return&lt;/span&gt; file, File&lt;span style="color: blue;"&gt;.&lt;/span&gt;ReadAllText file &lt;span style="color: blue;"&gt;}&lt;/span&gt;&lt;span style="color: blue;"&gt;]&lt;/span&gt;&lt;span style="color: blue;"&gt;)&lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp; &lt;span style="color: blue;"&gt;let&lt;/span&gt; harvest_data &lt;span style="color: blue;"&gt;(&lt;/span&gt;data&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;&lt;span style="color: blue;"&gt;)&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;:&lt;/span&gt; seq&amp;lt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;&amp;gt; = 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; seq &lt;span style="color: blue;"&gt;{&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;for&lt;/span&gt; line &lt;span style="color: blue;"&gt;in&lt;/span&gt; String&lt;span style="color: blue;"&gt;.&lt;/span&gt;lines data &lt;span style="color: blue;"&gt;do&lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; not &lt;span style="color: blue;"&gt;(&lt;/span&gt;line&lt;span style="color: blue;"&gt;.&lt;/span&gt;StartsWith &lt;span style="color: maroon;"&gt;"#"&lt;/span&gt;&lt;span style="color: blue;"&gt;)&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;then&lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield line&lt;span style="color: blue;"&gt;.&lt;/span&gt;Split&lt;span style="color: blue;"&gt;(&lt;/span&gt;&lt;span style="color: blue;"&gt;[|&lt;/span&gt;&lt;span style="color: maroon;"&gt;' '&lt;/span&gt;&lt;span style="color: blue;"&gt;|]&lt;/span&gt;&lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: blue;"&gt;.&lt;/span&gt;&lt;span style="color: blue;"&gt;[&lt;/span&gt;&lt;span style="color: maroon;"&gt;2&lt;/span&gt;&lt;span style="color: blue;"&gt;]&lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;}&lt;/span&gt;&lt;/div&gt;

&lt;div style="font-family: courier new;"&gt;&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;/div&gt;

&lt;p&gt;Finally, we can count get the IP occurrence count by implementing our map and reduce functions and calling our map_reduce implementation.&amp;nbsp; &lt;/p&gt;

&lt;div style="font-family: courier new;"&gt;&amp;nbsp; &lt;span style="color: blue;"&gt;let&lt;/span&gt; ip_occurrence_count &lt;span style="color: blue;"&gt;:&lt;/span&gt; Map&amp;lt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;, &lt;span style="color: blue;"&gt;string&lt;/span&gt;&amp;gt; &lt;span style="color: blue;"&gt;-&amp;gt;&lt;/span&gt; Map&amp;lt;&lt;span style="color: blue;"&gt;string&lt;/span&gt;, &lt;span style="color: blue;"&gt;int&lt;/span&gt;&amp;gt; = 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;let&lt;/span&gt; m = const' &lt;span style="color: blue;"&gt;(&lt;/span&gt;harvest_data &amp;gt;&amp;gt; Seq&lt;span style="color: blue;"&gt;.&lt;/span&gt;map&lt;span style="color: blue;"&gt;(&lt;/span&gt;flip Tuple&lt;span style="color: blue;"&gt;.&lt;/span&gt;curry &lt;span style="color: maroon;"&gt;1&lt;/span&gt;&lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: blue;"&gt;)&lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;let&lt;/span&gt; r = const' &lt;span style="color: blue;"&gt;(&lt;/span&gt;Seq&lt;span style="color: blue;"&gt;.&lt;/span&gt;sum &amp;gt;&amp;gt; Some&lt;span style="color: blue;"&gt;)&lt;/span&gt;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MapReduce&lt;span style="color: blue;"&gt;.&lt;/span&gt;map_reduce m r

  &lt;br&gt;&amp;nbsp; &lt;br&gt;&lt;span style="color: blue;"&gt;module&lt;/span&gt; MainModule = 

  &lt;br&gt;&amp;nbsp; &lt;span style="color: blue;"&gt;[&amp;lt;&lt;/span&gt;EntryPoint&lt;span style="color: blue;"&gt;&amp;gt;]&lt;/span&gt; 

  &lt;br&gt;&amp;nbsp; &lt;span style="color: blue;"&gt;let&lt;/span&gt; main&lt;span style="color: blue;"&gt;(&lt;/span&gt;args&lt;span style="color: blue;"&gt;:&lt;/span&gt;&lt;span style="color: blue;"&gt;string&lt;/span&gt; array&lt;span style="color: blue;"&gt;)&lt;/span&gt; = 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; printfn &lt;span style="color: maroon;"&gt;"%A"&lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;(&lt;/span&gt;LogCount&lt;span style="color: blue;"&gt;.&lt;/span&gt;ip_occurrence_count 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;(&lt;/span&gt;Map&lt;span style="color: blue;"&gt;.&lt;/span&gt;of_seq LogCount&lt;span style="color: blue;"&gt;.&lt;/span&gt;processed_logs&lt;span style="color: blue;"&gt;)&lt;/span&gt;&lt;span style="color: blue;"&gt;)&lt;/span&gt; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: maroon;"&gt;0&lt;/span&gt;&lt;/div&gt;

&lt;div style="font-family: courier new;"&gt;&lt;span style="color: maroon;"&gt;&lt;/span&gt;&lt;/div&gt;

&lt;p&gt;The m function above harvests the data from the string value and then mark each IP address with an occurrence of 1.&amp;nbsp; Then our reduce function will sum the sequence of 1s for each given key to produce our result.&amp;nbsp; There is some boilerplate code that has been omitted due to space constraints but will be available at the end of this post.&amp;nbsp; Once we run this against a known set of data, we might get the following results:&lt;/p&gt;

&lt;div style="font-family: courier new;"&gt;seq 
  &lt;br&gt;&amp;nbsp; [[192.168.1.2, 46]; [192.168.1.8, 339]; 

  &lt;br&gt;&amp;nbsp;&amp;nbsp; [192.168.1.10, 11]; [192.168.1.15, 43]] 

  &lt;br&gt;Press any key to continue . . .&lt;/div&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;With this simple example, we can see some of the power and possibilities such a programming model can bring.&amp;nbsp; This exercise is more of an idea of how one might be written using the programming model, as I didn’t write any system to handle concurrency, scheduling and so on.&amp;nbsp; &lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;In many of my adventures in big data analysis and data parallel concurrency, MapReduce is one of the more interesting solutions.&amp;nbsp; By utilizing functional programming constructs, we are able to write rich code to analyze our data that may not as structured as we wish.&amp;nbsp; But, does our adventure stop here with this implementation?&amp;nbsp; Not necessarily, but either way it was a lot of fun.&lt;/p&gt;

&lt;p&gt;You can find the source code for this example &lt;a href="http://codebetter.com/blogs/matthew.podwysocki/MapReduce.zip" mce_href="http://codebetter.com/blogs/matthew.podwysocki/MapReduce.zip"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6935989" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Concurrency/default.aspx">Concurrency</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Frameworks/default.aspx">Frameworks</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Haskell/default.aspx">Haskell</category></item></channel></rss>