<?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 : Erlang</title><link>http://weblogs.asp.net/podwysocki/archive/tags/Erlang/default.aspx</link><description>Tags: Erlang</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><item><title>[ANN] DC ALT.NET 9/10/2009 – Webmachine with Kevin Smith</title><link>http://weblogs.asp.net/podwysocki/archive/2009/09/04/ann-dc-alt-net-9-10-2009-webmachine-with-kevin-smith.aspx</link><pubDate>Fri, 04 Sep 2009 19:27:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7192155</guid><dc:creator>podwysocki</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/podwysocki/rsscomments.aspx?PostID=7192155</wfw:commentRss><comments>http://weblogs.asp.net/podwysocki/archive/2009/09/04/ann-dc-alt-net-9-10-2009-webmachine-with-kevin-smith.aspx#comments</comments><description>&lt;P&gt;This month, &lt;A href="http://tech.groups.yahoo.com/group/dcaltnet/" mce_href="http://tech.groups.yahoo.com/group/dcaltnet/"&gt;DC ALT.NET&lt;/A&gt; is moving the meeting a little forward this month and teaming with &lt;A href="http://groups.google.com/group/novalanguages" mce_href="http://groups.google.com/group/novalanguages"&gt;NOVALANG&lt;/A&gt; and the &lt;A href="http://www.meetup.com/erlang/" mce_href="http://www.meetup.com/erlang/"&gt;Erlang Users of Arlington/DC&lt;/A&gt; to talk about the Webmachine REST Toolkit.&amp;nbsp; We at DC ALT.NET continue to strive to push developers to look outside their normal surroundings and comfort zones and this month is no different.&amp;nbsp; Details are below: &lt;/P&gt;
&lt;H2&gt;Getting Some REST with Erlang and Webmachine &lt;/H2&gt;
&lt;P&gt;Kevin Smith of &lt;A href="http://hypotheticalabs.com/" mce_href="http://hypotheticalabs.com/"&gt;Hypothetical Labs&lt;/A&gt; will be speaking about &lt;A href="http://bitbucket.org/justin/webmachine/wiki/Home" mce_href="http://bitbucket.org/justin/webmachine/wiki/Home"&gt;WebMachine&lt;/A&gt;: an erlang REST toolkit which makes it easy to develop HTTP interfaces using Erlang.&amp;nbsp; Providing RESTful interfaces is quickly becoming the norm for modern websites. There's more to REST than handling GETs and POSTs, though. This talk will illustrate how the combination of Erlang and webmachine simplifies and speeds the development of REST resources. &lt;/P&gt;
&lt;H2&gt;About Kevin Smith&lt;/H2&gt;
&lt;P&gt;Kevin Smith has, at various times, been a network administrator, DBA, developer, team lead and trainer over his 14 year career. He ﬁrst learned about Erlang in 2006 via Joe Armstrong's excellent “Programming Erlang” and has never looked back. He attended the first (and only?) Erlang Studio where he was asked to produce what became the popular PragProg screencast series "Erlang In Practice". Until recently, Kevin was a developer at Engine Yard where he worked on a distributed systems management application using Erlang. Kevin founded &lt;A href="http://www.hypotheticalabs.com/" mce_href="http://www.hypotheticalabs.com/"&gt;Hypothetical Labs&lt;/A&gt; in April of this year to focus on Erlang full time. He is also the co-author of the upcoming book "Erlang Web Application Development".&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Date/Time:&lt;/STRONG&gt; 9/10/2009 – 7-9PM&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Location: &lt;BR&gt;&lt;/STRONG&gt;The Motley Fool &lt;BR&gt;2000 Duke Street &lt;BR&gt;Alexandria, VA 22314&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.eventbrite.com/event/418055415?ref=ebtn" target=_blank mce_href="http://www.eventbrite.com/event/418055415?ref=ebtn"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; BORDER-TOP: 0px; BORDER-RIGHT: 0px" border=0 src="http://www.eventbrite.com/registerbutton?eid=418055415" mce_src="http://www.eventbrite.com/registerbutton?eid=418055415"&gt;&lt;/A&gt;&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7192155" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/podwysocki/archive/tags/ALT.NET/default.aspx">ALT.NET</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/User+Groups/default.aspx">User Groups</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Web+Development/default.aspx">Web Development</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Erlang/default.aspx">Erlang</category></item><item><title>The “Anti-For” Campaign</title><link>http://weblogs.asp.net/podwysocki/archive/2009/06/26/the-anti-for-campaign.aspx</link><pubDate>Fri, 26 Jun 2009 04:38:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7134577</guid><dc:creator>podwysocki</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/podwysocki/rsscomments.aspx?PostID=7134577</wfw:commentRss><comments>http://weblogs.asp.net/podwysocki/archive/2009/06/26/the-anti-for-campaign.aspx#comments</comments><description>&lt;p&gt;Recently, there has been an effort launched called the &lt;a href="http://www.antiifcampaign.com/" mce_href="http://www.antiifcampaign.com/"&gt;“Anti-If Campaign”&lt;/a&gt; in which they deride the use of if statements and instead, focus on Object Oriented Principles in order to create more flexible designs.&amp;nbsp; Now certainly, I have a sympathetic ear to this cause as I’ve seen code that literally walks off the side of the screen due to nesting of if statements.&amp;nbsp; Pattern matching to me, especially at the top level of the function is actually quite beautiful in a way, such as the implementations in Haskell:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:c847654b-3dff-4fd4-928b-52fdb03c6f0a" 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; Haskell&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;lucas :: 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; Integer
lucas &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, 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;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
lucas &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; &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;
lucas 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; lucas (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; &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(0, 0, 0);"&gt;+&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; lucas (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; &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;/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 in Erlang, this also holds true:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:309094f4-0c8d-4e93-83af-86ac469bbdba" 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, 0);"&gt; Erlang
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-module&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(lucascalc).
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-export&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;([lucas&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;]).

lucas(&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, 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;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;
lucas(&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;-&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;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;
lucas(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; lucas (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; &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(0, 0, 0);"&gt;+&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; lucas (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; &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;/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;Simple, easy to understand and best of all, no if statements.&amp;nbsp; But, instead of focus on this debate, I’d like to propose another which strikes closer to this functional programmers heart, the “Anti-For Campaign”.&amp;nbsp; This is simply to say that we should create and use composable functions instead of explicit for loops.&amp;nbsp; This is actually an old post I had written months ago and until now had been unfinished, but now with some inspiration, it’ll finally be done.&lt;/p&gt;

&lt;h2&gt;What and Why?&lt;/h2&gt;

&lt;p&gt;Before you throw all sorts of questions asking what and why, let me instead ask a question.&amp;nbsp; When you’re writing a loop, ask yourself the question, “What am I accomplishing in this loop?”&amp;nbsp; Chances are, it might be one of the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Query (Map, Filter, etc)&lt;/li&gt;

  &lt;li&gt;Aggregation (Sum, Count, etc)&lt;/li&gt;

  &lt;li&gt;Perform some side effect&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re doing more than one of those in a single loop, then well, you’re probably doing too much.&amp;nbsp; In fact, Martin Fowler’s Refactoring site has a refactoring called &lt;a href="http://www.refactoring.com/catalog/splitLoop.html" mce_href="http://www.refactoring.com/catalog/splitLoop.html"&gt;“Split Loop”&lt;/a&gt; which would solve that issue.&amp;nbsp; It is better for future refactorings and readability if we keep those loops pointed to do one thing, and one thing only.&amp;nbsp; Better yet, we could rid ourselves of that loop altogether, and that’s what we’ll focus on here.&lt;/p&gt;

&lt;p&gt;Looking at first two bullet points, you’ll notice most of LINQ is indeed built around those two to be able to query data as well as aggregate.&amp;nbsp; The final bullet point, we perform some sort of side effect, perhaps writing to a file, printing to the console, or even perhaps sending messages.&amp;nbsp; &lt;/p&gt;

&lt;p&gt;So, what’s my problem with them?&amp;nbsp; My problem is that it focuses more on the How instead of the What.&amp;nbsp; Let’s look at a quick example down below of what I mean.&amp;nbsp; First, we’ll attempt to find all prime numbers under 100 using C# as an example language.&amp;nbsp; First in the How:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:e7517c49-06cc-4423-a641-fec8ee8a3894" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&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;bool&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; IsPrime(&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, 255);"&gt;var&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; lim &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Math.Sqrt(i);
    
    Func&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;, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;bool&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; check &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;null&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;
    check &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; j &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;
        j &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; lim &lt;/span&gt;&lt;span style="color: rgb(0, 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, 0);"&gt;%&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; j &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, 0);"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; check(j &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;1&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; check(&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(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;void&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Main(&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;[] args) {
    &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; numbers &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Enumerable.Range(&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;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;var&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; output &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; List&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;span style="color: rgb(0, 0, 255);"&gt;foreach&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; number &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; numbers)
        &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;(IsPrime(number)) output.Add(number);
}&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 is that if we then want to compose another operation, well, it’s really hard to do inside of these for loops.&amp;nbsp; We’re too focused on the how at this point.&amp;nbsp; Instead, getting to know generics and lazy evaluation, in .NET 2.0 and beyond, we were able to write generic functions to take advantage of some functional constructs.&amp;nbsp; This will give us a more declarative style that we can now focus on the what.&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:59330329-7867-403f-a083-540beaf692a4" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; IEnumerable&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;T&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; Filter&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;T&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, 255);"&gt;this&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; IEnumerable&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;T&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; items,
    Func&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;T, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;bool&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; predicate) {
    
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;foreach&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; item &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; items)
        &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;(predicate(item))
            &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; &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; item;
}

&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;void&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Main(&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;[] args) {
    &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; numbers &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Enumerable.Range(&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;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;var&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; primes &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; items.Filter(x &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; IsPrime(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;Of course we realize that LINQ already has such constructs built in, so we could rewrite the entire code above in just one statement.&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:63f23cd3-baf9-46ca-8d50-517f5ebabdfb" 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; primes &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Enumerable.Range(&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;100&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
    .Where(x &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; IsPrime(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;And what’s better is that it is composable that we could do other operations such as aggregations (sum, count, etc) without much additional code:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:3953a208-84d3-401f-9f1c-c451beab8611" 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; primesCount &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Enumerable.Range(&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;100&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
    .Where(x &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; IsPrime(x))
    .Count();&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 there you have it.&amp;nbsp; We not only have a query, but also an aggregation.&amp;nbsp; Try doing that with those non-composable loops!&amp;nbsp; &lt;a href="http://www.codethinked.com/post/2009/06/15/Life-After-Loops.aspx" mce_href="http://www.codethinked.com/post/2009/06/15/Life-After-Loops.aspx"&gt;Justin Etheredge has a nice writeup&lt;/a&gt; as well recently on the subject.&lt;/p&gt;

&lt;h2&gt;Coping Strategies&lt;/h2&gt;

&lt;p&gt;Functional languages tend to deemphasize the use of such constructs.&amp;nbsp; In fact, Haskell has neither a for loop nor a while loop, and languages such as F# and OCaml have limited support for such constructs in terms of no break and continue.&amp;nbsp; We tend to look at those two in particular with suspicion due to the fact that it cannot return a value and instead it mutates state in some fashion.&amp;nbsp; With that in mind, how do we cope with the fact that those aren’t available to us?&amp;nbsp; Above I showed a basic concept of a filter instead of an explicit loop, but what about some other considerations?&lt;/p&gt;

&lt;p&gt;Some things we might want to consider with some links to some of my previous posts on the subject:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://codebetter.com/blogs/matthew.podwysocki/archive/2008/08/13/recursing-on-recursion-continuation-passing.aspx" mce_href="http://codebetter.com/blogs/matthew.podwysocki/archive/2008/08/13/recursing-on-recursion-continuation-passing.aspx"&gt;Explicit Recursion&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;Transforming each item (Map/Select &amp;amp; SelectMany in LINQ)&lt;/li&gt;

  &lt;li&gt;Selecting items (Filter/Where in LINQ)&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://codebetter.com/blogs/matthew.podwysocki/archive/2009/02/14/fun-with-folds.aspx" mce_href="http://codebetter.com/blogs/matthew.podwysocki/archive/2009/02/14/fun-with-folds.aspx"&gt;Aggregating Data&lt;/a&gt; (Folds/Aggregate in LINQ)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In fact, many times that people could consider using explicit recursion could instead use a fold to aggregate the data which then cuts out the issue of tail call optimization.&amp;nbsp; By truly understanding the goals of LINQ as well as the concepts of functional programming, we can realize that most of the looping that we do can indeed be replaced by the above, outside of side effects of course.&lt;/p&gt;

&lt;h2&gt;Now What About Those Side Effects?&lt;/h2&gt;

&lt;p&gt;Is there a place where we draw the line and say that explicit loops are ok?&amp;nbsp; Eric Lippert was recently asked about the reasoning of the &lt;a href="http://blogs.msdn.com/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx"&gt;lack of the ForEach extension method on IEnumerable&amp;lt;T&amp;gt;&lt;/a&gt;.&amp;nbsp; His response was that he was philosophically opposed to such an endeavor as the whole approach is to cause a side effect.&amp;nbsp; As IEnumerable&amp;lt;T&amp;gt; collections are immutable, he doesn’t believe it makes as much sense because you wouldn’t be side effecting the collection itself.&amp;nbsp; Not only that, but introducing closures can complicate object lifetimes and all sorts of potential reference issues.&lt;/p&gt;

&lt;p&gt;What about me?&amp;nbsp; I understand his concerns, and in C#, I can certainly see where he is coming from.&amp;nbsp; However, in F# we have such constructs readily available to us in the iter and iteri functions as shown below in F# Interactive:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:62c5fb8e-73f1-4057-b68c-f2ee5de6ee16" 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; flip f y 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; 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; [&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;10&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;|&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; List.map((&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;2&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;|&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; List.filter(flip (&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;3&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;&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(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, 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; List.iter(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;%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;);;
&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;6&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(128, 0, 128);"&gt;18&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(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;10&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;|&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; List.map((&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;2&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;|&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; List.filter(flip (&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;3&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;&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(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, 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; List.iteri(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;%d\t%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;);;
&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;6&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;       &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(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;18&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;Outside of logging, writing to the console and such are rare in functional programming, so once again, I can certainly understand the concern.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;I hope by going through some basic scenarios that we will indeed question our code the next time we see that we are writing that explicit loop with a for and a while.&amp;nbsp; With a tool chest filled with such functions as transforming every item, to filtering content, to aggregating data and so on, we can realize that we can create composable solutions instead of creating mutable collections or mutable variables and aggregating to them which are not as much.&amp;nbsp; So, come and join me in the “Anti-For Campaign”.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7134577" 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/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><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Erlang/default.aspx">Erlang</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><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/F_2300_/default.aspx">F#</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Concurrency/default.aspx">Concurrency</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Haskell/default.aspx">Haskell</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Axum/default.aspx">Axum</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Erlang/default.aspx">Erlang</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><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/F_2300_/default.aspx">F#</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Concurrency/default.aspx">Concurrency</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/Axum/default.aspx">Axum</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Erlang/default.aspx">Erlang</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><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/F_2300_/default.aspx">F#</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Concurrency/default.aspx">Concurrency</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Axum/default.aspx">Axum</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Erlang/default.aspx">Erlang</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><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/F_2300_/default.aspx">F#</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Concurrency/default.aspx">Concurrency</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Haskell/default.aspx">Haskell</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Axum/default.aspx">Axum</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Erlang/default.aspx">Erlang</category></item><item><title>Axum – Introduction and Ping Pong Example</title><link>http://weblogs.asp.net/podwysocki/archive/2009/05/12/axum-introduction-and-ping-pong-example.aspx</link><pubDate>Tue, 12 May 2009 05:37:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7083483</guid><dc:creator>podwysocki</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/podwysocki/rsscomments.aspx?PostID=7083483</wfw:commentRss><comments>http://weblogs.asp.net/podwysocki/archive/2009/05/12/axum-introduction-and-ping-pong-example.aspx#comments</comments><description>&lt;p&gt;As it was &lt;a href="http://blogs.msdn.com/maestroteam/archive/2009/05/07/the-first-axum-bits-are-now-available.aspx" mce_href="http://blogs.msdn.com/maestroteam/archive/2009/05/07/the-first-axum-bits-are-now-available.aspx"&gt;announced last week&lt;/a&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;Axum, a .NET Domain Specific Language&lt;/a&gt; around safe, scalable parallel programming through the actor model and message passing was released to the world as a CTP.&amp;nbsp; It was noted, that although this is an initial release, that this is still an incubation project which may or may not lead to a final product.&amp;nbsp; This post will serve as a kind of introduction to the language and some basic concepts.&lt;/p&gt;

&lt;h2&gt;Just A Brief Introduction&lt;/h2&gt;

&lt;p&gt;Before we get started, I wanted to make sure that we had a basic introduction to the language.&amp;nbsp; The question often comes up, why another .NET language?&amp;nbsp; Many people feel that with such others as C#, VB.NET, now F#, IronPython and IronRuby, that maybe we have enough languages already to solve most of our programming needs.&amp;nbsp; But there remains one important, yet untackled problem around making coordinated parallelization easy.&amp;nbsp; Sure, we have such things as the Parallel Extensions for .NET being baked into .NET 4.0, which gives us the Task Parallel Library, Parallel LINQ and so on, but none of these really address the intricate nature of coordinated parallelization.&lt;/p&gt;

&lt;p&gt;Typically, when we’re developing these parallel applications, we could partition the data as usual and then scatter them out as parallel tasks.&amp;nbsp; Some jobs were meant for solutions such as this, but others might require a bit more coordination.&amp;nbsp; The Axum language, built upon the &lt;a href="http://msdn.microsoft.com/en-us/library/bb648752.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb648752.aspx"&gt;Microsoft Concurrency and Coordination Runtime&lt;/a&gt; from the Microsoft Robotics Studio, allows for a pretty natural language around such concepts as messaging, side effect free programming, but just as well, free yourself of many concurrency related bugs.&amp;nbsp; Because isolation is built-in as a default, one of the major sources of concurrency related bugs is taken away.&amp;nbsp; Just as well, when we design our applications with messaging in mind, we are building a scalable solution where concurrency isn’t an afterthought.&lt;/p&gt;

&lt;p&gt;So, the final word is, why a language?&amp;nbsp; Built-in isolation, easy to understand syntax around messaging, easy asynchronous programming model and many other benefits we get by stepping outside of the C# bounds.&amp;nbsp; The real question then becomes, so what?&amp;nbsp; What can we do with it?&lt;/p&gt;

&lt;h2&gt;The Erlang Way&lt;/h2&gt;

&lt;p&gt;When learning language concepts, I find it easier to spend some time in the language which most strongly implements that concept.&amp;nbsp; This way, I learn the concepts best when they are first-class citizens in the space.&amp;nbsp; For learning functional programming, I don’t think it’s as wise to spend your time hacking on C# as to instead learn on a more functional language such as Haskell.&amp;nbsp; Often when people ask how best to learn FP concepts, often Haskell comes into the equation and has obviously improved my F# code as well as some of my C# as well.&amp;nbsp; The same applies to a language with actor model concurrency as a built-in concept, where I can learn from my time spent in Erlang as a good precursor to what I can do in Axum.&lt;/p&gt;

&lt;p&gt;One of the really elementary things to do in Erlang is a simple &lt;a href="http://erlang.org/doc/getting_started/conc_prog.html" mce_href="http://erlang.org/doc/getting_started/conc_prog.html"&gt;ping-pong example&lt;/a&gt;.&amp;nbsp; In this simple example, we create two processes, a pinger and a ponger, and send messages between them a number of times.&amp;nbsp; Such 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:ba40d1c8-6aee-4910-ae2e-720e4a871eb7" 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;(tut15).

&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;-export&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;([start&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;, ping&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;/&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;, pong&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;]).

ping(&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;, Pong_PID) &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_PID &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,
    io:format(&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~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;, []);

ping(N, Pong_PID) &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_PID &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, self()},
    &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 &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;
            io:format(&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~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;end&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;,
    ping(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; &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;, Pong_PID).

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(0, 0, 255);"&gt;receive&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;-&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
            io:format(&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~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;, []);
        {ping, Ping_PID} &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;
            io:format(&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~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;, []),
            Ping_PID &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,
            pong()
    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;end&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.

start() &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_PID &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; spawn(tut15, pong, []),
    spawn(tut15, ping, [&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;, Pong_PID]).&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;From this example, we have two functions, a ping and a pong.&amp;nbsp; Our ping has an arity with two arguments, the iteration number and the Process ID (PID) of the pong.&amp;nbsp; If we are at zero iterations left, then we sent the finished message back to the pong’s PID, else we send a ping to the pong, then receive our pong message and then recurse to decrement the iteration number.&amp;nbsp; Pretty simple, elegant and straight forward example.&amp;nbsp; Running this example, we might get the following:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:c1b75ed7-1e3c-47fb-bbbb-e731bf8d4170" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Erlang R13B (erts&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;-&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;5.7&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;) [smp:&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;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;] [rq:&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;] [async&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;-&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;threads:&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;]

Eshell V5.&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;7.1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;  (abort 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;G)
&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;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; c(tut15).
{ok,tut15}
&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;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; tut15:start().
Pong received ping
&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;0.40&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;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;
Ping received pong
Pong received ping
Ping received pong
Pong received ping
Ping received pong
ping finished
Pong finished&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 &amp;lt;0.40.0&amp;gt; value you see above is the return value from the start() function which is nothing more than the PID of the ping process.&amp;nbsp; Now that we’ve seen this in action in Erlang, how could we do the same in Axum?&lt;/p&gt;

&lt;h2&gt;The Axum Solution&lt;/h2&gt;

&lt;p&gt;We have a couple of options when implementing this ping-pong example in Axum.&amp;nbsp; First, we have approach using channels, and another using an ordered interaction point.&amp;nbsp; Let’s walk through each of these solutions as a possible implementation.&amp;nbsp; The Axum Programming Guide is a great reference just in case you want to dive deeper into some of these topics.&lt;/p&gt;

&lt;p&gt;Before we get started here, let’s first take a look at a simple hello world example to get you familiar with the syntax.&amp;nbsp; Below is a quick example of getting the command line arguments, and then setting the channel to say we are finished.&amp;nbsp; Alternatively, we could set the error code &lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:9538c87d-3785-4275-92d5-6f85b6cb3624" 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; Microsoft.Axum;

&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; Wait for the command line arguments&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; cmdLine &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; PrimaryChannel::CommandLine;
        &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; cmdArgs &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;receive&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(cmdLine);  
        
        &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Tell the application we're done&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;
&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;&amp;lt;--&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;The first piece you will notice is the lack of the word class, and instead the keyword agent.&amp;nbsp; The agent concept comes from the actor model of concurrency in which it is an autonomous entity that communicates with others via messages they receives from these other “actors” and can spawn off other “actors” as well.&amp;nbsp; These agents aren’t like normal classes in which you have fields that other classes can modify, nor have any direct method calls you can make.&amp;nbsp; &lt;/p&gt;

&lt;p&gt;The second piece you’ll notice after the agent declaration is that our Program implements the Microsoft.Axum.Application Channel.&amp;nbsp; When we implement a channel, we are attached at the implementing end of that channel and we become the server of messages on that channel.&amp;nbsp; This channel has a public property called PrimaryChannel which gives access to the channel being implemented.&amp;nbsp; The double-colon operator gives us access to the channel’s port.&lt;/p&gt;

&lt;p&gt;Now to actually dive through the agent constructor, we wait for the command line arguments to be passed.&amp;nbsp; This receive is a blocking call, so we will wait until we receive the data from the CommandLine port, which in this case will be a string array.&amp;nbsp; We then tell the application we are done by sending a message through the &amp;lt;—operator to the Done port, which is done asynchronously, as opposed to the receive.&amp;nbsp; Now that we looked at a basic example, let’s move on to a channel based approach.&lt;/p&gt;

&lt;h2&gt;The Channels Example&lt;/h2&gt;

&lt;p&gt;The first example we’re going to look at is using channels and protocols.&amp;nbsp; In this example, we will use some of the above constructs with the addition of channel protocols.&amp;nbsp; First, let’s look at the main code which starts the program:&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:3c4099d3-8c55-48b5-97a5-85e88a5771bf" 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; System.Collections.Generic;
&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; Wait for our command args&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; cmdArgs &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;receive&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(PrimaryChannel::CommandLine);
        
        &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Set the iterations to be some number&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; iters &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;3&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; 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; 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; Receive how many done&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;receive&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(chan::Done);
        
        PrimaryChannel::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;/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 code first waits for our command arguments, then we set the iterations to 3 for now, but we could set it as high as we wish, maybe higher than 5000 if we care.&amp;nbsp; Sure, that’s a high number, but our system should be good for it.&amp;nbsp; We then call Ping.CreateInNewDomain() which instantiates two ends of the PingPongStatus channel, creates an instance of Ping that implements the channel, then returns the using end of the channel.&amp;nbsp; After this, we send a message on the HowMany port with our number of iterations desired.&amp;nbsp; Then, we’ll block until we’ve received our message on the Done port to indicate that we are finished.&amp;nbsp; Finally, we wrap up with setting the overall Done on the PrimaryChannel to indicate our program completion.&amp;nbsp; Let’s move onto the Ping implementation next.&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:a9523749-e169-4113-aa77-cec2050be31a" 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;
    &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; &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; Done;
    
    Start: { HowMany, 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; 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()
    {
        &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; How many are we supposed to do?&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; iters &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;receive&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(PrimaryChannel::HowMany);
        
        &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 and send how many to do&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();      
        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; 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; 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;);
        }
        
        &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; How many did Pong process?&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;int&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; pongIters &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;receive&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(chan::Done);

        PrimaryChannel::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; &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;/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;First, we created a PingPongStatus channel to get an input of how many to process, and then we have an output message which says we’re complete.&amp;nbsp; You’ll notice there’s something more to our channel which begins with Start:.&amp;nbsp; This is an implementation of a protocol, which allows us to specify the order in which messages are sent to which ports.&amp;nbsp; All cases start with the Start as we have above, and then we transition to the HowMany port, then from the Done, it signifies the end of our interaction on this channel.&lt;/p&gt;

&lt;p&gt;Now to analyze the Ping agent.&amp;nbsp; Quite simply, we receive the number of iterations message from our Program agent from above.&amp;nbsp; From there, we call Pong.CreateInNewDomain() which instantiates two ends of the PingPong channel, creates an instance of Pong that implements the channel, then returns the using end of the channel.&amp;nbsp; We send a message to the HowMany port to specify the number of iterations our ponger should do.&amp;nbsp; Going through each iteration, we send a message on the Ping port of a Signal, receive the message back on the Pong port.&amp;nbsp; Finally, we receive the number of iterations that our pong did and then set our Done flag to 0.&amp;nbsp; Now, let’s move onto our Pong implementation.&lt;/p&gt;

&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:47173b24-eb68-45b2-a747-2c08e42bc703" 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; &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;
    &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; &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; 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, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Get how many we're supposed to do&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; iters &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;receive&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(PrimaryChannel::HowMany);

        &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;;

        &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Receive our ping and send back our 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;for&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;)
        {
            &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;(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;    
        }
    
        PrimaryChannel::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; i;
    }
}&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;Notice that we have defined our PingPong channel to have ports to indicate how many to do, an output of how many we did, plus an input of a ping and an output of a pong.&amp;nbsp; Pretty straight forward and self explanatory.&amp;nbsp; Our Pong agent receives the number of iterations we’re supposed to do.&amp;nbsp; Then we loop through our iterations, receiving a ping and sending a pong.&amp;nbsp; After we finish the loop, we send a message on the Done port to indicate the number of iterations done.&amp;nbsp; &lt;/p&gt;

&lt;p&gt;If we stick with our three iterations, the output from our application should 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:33a971dd-4bf0-4dbf-b1db-71d11a267536" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 255);"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Pong received Ping
Ping Received Pong
Pong received Ping
Ping Received Pong
Pong received Ping
Ping Received Pong&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;Pretty straight forward and easy example as we dip our toe into what we can do with Axum.&amp;nbsp; You can find the complete source code &lt;a href="http://gist.github.com/110275" mce_href="http://gist.github.com/110275"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;There 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; Until then, I hope this brief foray into some of the capabilities of Axum will inspire you to give Axum a look.&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; 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=7083483" 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/Axum/default.aspx">Axum</category><category domain="http://weblogs.asp.net/podwysocki/archive/tags/Erlang/default.aspx">Erlang</category></item></channel></rss>