<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>DevHawk</title><link>http://devhawk.net/</link><description>Passion * Technology * Ruthless Competence</description><language>en-us</language><copyright>Harry Pierson</copyright><managingEditor>harry@devhawk.net</managingEditor><lastBuildDate>Thu, 04 Sep 2008 00:00:00 -0500</lastBuildDate><generator>newtelligence dasBlog 2.0.7226.0</generator><geo:lat>47.640972</geo:lat><geo:long>-122.033189</geo:long><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/Devhawk" type="application/rss+xml" /><feedburner:browserFriendly>(Enter a personal message you would like to have appear at the top of your feed.)</feedburner:browserFriendly><item><title>Links for 2008-09-03 [del.icio.us]</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/382956715/harrypierson</link><pubDate>Thu, 04 Sep 2008 00:00:00 -0500</pubDate><guid isPermaLink="false">http://del.icio.us/harrypierson#2008-09-03</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<ul>
<li><a href="http://www.opshopmusic.com/">Opshop</a><br/>
This band played at the TechEd New Zealand attendee party. I thought they were pretty good.</li>
</ul>]]></content:encoded><description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.opshopmusic.com/"&gt;Opshop&lt;/a&gt;&lt;br/&gt;
This band played at the TechEd New Zealand attendee party. I thought they were pretty good.&lt;/li&gt;
&lt;/ul&gt;</description><feedburner:origLink>http://del.icio.us/harrypierson#2008-09-03</feedburner:origLink></item><item><title>Morning Coffee 173</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/378381394/Morning+Coffee+173.aspx</link><category>F#</category><category>IronPython</category><category>IronRuby</category><category>Morning Coffee</category><category>WF</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Harry Pierson</dc:creator><pubDate>Fri, 29 Aug 2008 15:29:09 -0500</pubDate><guid isPermaLink="false">http://devhawk.net/PermaLink,guid,a50f3ddf-941b-43ae-890a-532f527d2849.aspx</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
        <p>
I'm on my way out the door for New Zealand and Australia, but I wanted to push out
a few things.
</p>
        <ul>
          <li>
F# <strike>August</strike> September CTP is out! Don Syme has the <a href="http://blogs.msdn.com/dsyme/archive/2008/08/29/the-f-september-2008-ctp-is-now-available.aspx">announcement</a>,
Jomo Fisher has the <a href="http://blogs.msdn.com/jomo_fisher/pages/f-1-9-6-0-link-roundup.aspx">link
roundup</a> and details are on the brand-spanking-new MSDN F# Dev Center. Major congrats
to the F# team. I've been running a pre-release version of these bits, and they are
a huge step forward if you're an F# developer. 
</li>
          <li>
I've got an <a href="http://www.code-magazine.com/Article.aspx?quickid=0809071">article
on IronPython</a> in the latest issue of CoDe magazine. Also check out <a href="http://bradwilson.typepad.com/">Brad
Wilson's</a><a href="http://www.code-magazine.com/Article.aspx?quickid=0809061">IronRuby
article</a>, <a href="http://blogs.tedneward.com/">Ted Neward's</a><a href="http://www.code-magazine.com/Article.aspx?quickid=0809051">F#
article</a> and <a href="http://memeagora.blogspot.com/">Neil Ford's</a><a href="http://www.code-magazine.com/Article.aspx?quickid=0809041">Polygot
Programming article</a>. 
</li>
          <li>
Via Michael Foord I discovered that IronPython tester Dave Fugate is <a href="http://knowbody.livejournal.com/">back
on the blog</a>. He starts with a <a href="http://knowbody.livejournal.com/6191.html">couple</a> of <a href="http://knowbody.livejournal.com/6442.html">posts</a> about
measuring IronPython performance. 
</li>
          <li>
Speaking of blogging teammates, I think the dynamic languages team has the highest
percentage of bloggers in any group at MSFT. All four Program Managers (<a href="http://blog.remlog.net/">Dave</a> (lead), <a href="http://www.iunknown.com/">John</a>, <a href="http://blog.jimmy.schementi.com/">Jimmy</a> and <a href="http://devhawk.net/">me</a>),
four of five developers (<a href="http://blogs.msdn.com/shrib">Shri</a> (lead), <a href="http://blogs.msdn.com/dinoviehland">Dino</a>, <a href="http://blogs.msdn.com/curth">Curt</a> and <a href="http://www.tkachenko.com/blog/">Oleg</a>)
and all three Testers (<a href="http://blog.jredville.com/">Jim</a>, <a href="http://knowbody.livejournal.com/">Dave</a> and <a href="http://blogs.msdn.com/srivatsn/default.aspx">Srivatsn</a>).
The only non blogger right now is Tomas - who at least has a <a href="http://tmd.havit.cz/">home
page</a> - and  the lead tester which is an open position right now. 11 bloggers
out of 12 team members equals 91.67% team blogger coverage. 
</li>
          <li>
I was really impressed with Newspeak when I <a href="http://www.langnetsymposium.com/talks/2-01%20-%20Newspeak%20-%20Gilad%20Braha%20-%20Cadence.html">saw
it at Lang.NET</a> so I'm very excited to see they have a <a href="http://newspeaklanguage.org/">new
website</a>. No public bits yet, but I like the part where they point out Newspeak
"can be implemented independently of Squeak, Smalltalk or any particular VM or IDE".
How about implementing a version on DLR guys? 
</li>
          <li>
Maurice de Beijer <a href="http://msmvps.com/blogs/theproblemsolver/archive/2008/08/25/using-an-ironpython-runtime-service-from-windows-workflow-foundation.aspx">shows
off</a> embedding IronPython inside a WF application. Kinda cool, but he's primarily
showing off implementing a CLR interface in IPy. How about a WF activity that execute
arbitrary IPy code. That would be cool. (via <a href="http://ironpython-urls.blogspot.com/2008/08/ironpython-and-windows-workflow.html">IronPython
URLs</a>) 
</li>
          <li>
            <a href="http://code.google.com/p/ironclad/">Ironclad</a> has <a href="http://groups.google.com/group/ironpy/browse_frm/thread/4baf2673c0f0afcf/6e5d15c5d01de5e">reached</a> their
0.5 milestone, being able to import numpy from IronPython. BTW, guys - I'm not sure
commenting out one line that appears to be unreferenced qualifies as a "monstrous
caveat". Congrats guys! (via <a href="http://ironpython-urls.blogspot.com/2008/08/ironclad-05-released-use-numpy-from.html">IronPython
URLs</a>)</li>
        </ul>
        <img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=a50f3ddf-941b-43ae-890a-532f527d2849"></img>
      <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Devhawk?a=fJQT4K"><img src="http://feeds.feedburner.com/~f/Devhawk?i=fJQT4K" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=T3ChFK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=T3ChFK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=VrbZLK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=VrbZLK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=OBJX6k"><img src="http://feeds.feedburner.com/~f/Devhawk?i=OBJX6k" border="0"></img></a>
</div>]]></content:encoded><description>&lt;p&gt;
I'm on my way out the door for New Zealand and Australia, but I wanted to push out
a few things.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
F# &lt;strike&gt;August&lt;/strike&gt; September CTP is out! Don Syme has the &lt;a href="http://blogs.msdn.com/dsyme/archive/2008/08/29/the-f-september-2008-ctp-is-now-available.aspx"&gt;announcement&lt;/a&gt;,
Jomo Fisher has the &lt;a href="http://blogs.msdn.com/jomo_fisher/pages/f-1-9-6-0-link-roundup.aspx"&gt;link
roundup&lt;/a&gt; and details are on the brand-spanking-new MSDN F# Dev Center. Major congrats
to the F# team. I've been running a pre-release version of these bits, and they are
a huge step forward if you're an F# developer. 
&lt;li&gt;
I've got an &lt;a href="http://www.code-magazine.com/Article.aspx?quickid=0809071"&gt;article
on IronPython&lt;/a&gt; in the latest issue of CoDe magazine. Also check out &lt;a href="http://bradwilson.typepad.com/"&gt;Brad
Wilson's&lt;/a&gt; &lt;a href="http://www.code-magazine.com/Article.aspx?quickid=0809061"&gt;IronRuby
article&lt;/a&gt;, &lt;a href="http://blogs.tedneward.com/"&gt;Ted Neward's&lt;/a&gt; &lt;a href="http://www.code-magazine.com/Article.aspx?quickid=0809051"&gt;F#
article&lt;/a&gt; and &lt;a href="http://memeagora.blogspot.com/"&gt;Neil Ford's&lt;/a&gt; &lt;a href="http://www.code-magazine.com/Article.aspx?quickid=0809041"&gt;Polygot
Programming article&lt;/a&gt;. 
&lt;li&gt;
Via Michael Foord I discovered that IronPython tester Dave Fugate is &lt;a href="http://knowbody.livejournal.com/"&gt;back
on the blog&lt;/a&gt;. He starts with a &lt;a href="http://knowbody.livejournal.com/6191.html"&gt;couple&lt;/a&gt; of &lt;a href="http://knowbody.livejournal.com/6442.html"&gt;posts&lt;/a&gt; about
measuring IronPython performance. 
&lt;li&gt;
Speaking of blogging teammates, I think the dynamic languages team has the highest
percentage of bloggers in any group at MSFT. All four Program Managers (&lt;a href="http://blog.remlog.net/"&gt;Dave&lt;/a&gt; (lead), &lt;a href="http://www.iunknown.com/"&gt;John&lt;/a&gt;, &lt;a href="http://blog.jimmy.schementi.com/"&gt;Jimmy&lt;/a&gt; and &lt;a href="http://devhawk.net/"&gt;me&lt;/a&gt;),
four of five developers (&lt;a href="http://blogs.msdn.com/shrib"&gt;Shri&lt;/a&gt; (lead), &lt;a href="http://blogs.msdn.com/dinoviehland"&gt;Dino&lt;/a&gt;, &lt;a href="http://blogs.msdn.com/curth"&gt;Curt&lt;/a&gt; and &lt;a href="http://www.tkachenko.com/blog/"&gt;Oleg&lt;/a&gt;)
and all three Testers (&lt;a href="http://blog.jredville.com/"&gt;Jim&lt;/a&gt;, &lt;a href="http://knowbody.livejournal.com/"&gt;Dave&lt;/a&gt; and &lt;a href="http://blogs.msdn.com/srivatsn/default.aspx"&gt;Srivatsn&lt;/a&gt;).
The only non blogger right now is Tomas - who at least has a &lt;a href="http://tmd.havit.cz/"&gt;home
page&lt;/a&gt; - and&amp;nbsp; the lead tester which is an open position right now. 11 bloggers
out of 12 team members equals 91.67% team blogger coverage. 
&lt;li&gt;
I was really impressed with Newspeak when I &lt;a href="http://www.langnetsymposium.com/talks/2-01%20-%20Newspeak%20-%20Gilad%20Braha%20-%20Cadence.html"&gt;saw
it at Lang.NET&lt;/a&gt; so I'm very excited to see they have a &lt;a href="http://newspeaklanguage.org/"&gt;new
website&lt;/a&gt;. No public bits yet, but I like the part where they point out Newspeak
"can be implemented independently of Squeak, Smalltalk or any particular VM or IDE".
How about implementing a version on DLR guys? 
&lt;li&gt;
Maurice de Beijer &lt;a href="http://msmvps.com/blogs/theproblemsolver/archive/2008/08/25/using-an-ironpython-runtime-service-from-windows-workflow-foundation.aspx"&gt;shows
off&lt;/a&gt; embedding IronPython inside a WF application. Kinda cool, but he's primarily
showing off implementing a CLR interface in IPy. How about a WF activity that execute
arbitrary IPy code. That would be cool. (via &lt;a href="http://ironpython-urls.blogspot.com/2008/08/ironpython-and-windows-workflow.html"&gt;IronPython
URLs&lt;/a&gt;) 
&lt;li&gt;
&lt;a href="http://code.google.com/p/ironclad/"&gt;Ironclad&lt;/a&gt; has &lt;a href="http://groups.google.com/group/ironpy/browse_frm/thread/4baf2673c0f0afcf/6e5d15c5d01de5e"&gt;reached&lt;/a&gt; their
0.5 milestone, being able to import numpy from IronPython. BTW, guys - I'm not sure
commenting out one line that appears to be unreferenced qualifies as a "monstrous
caveat". Congrats guys! (via &lt;a href="http://ironpython-urls.blogspot.com/2008/08/ironclad-05-released-use-numpy-from.html"&gt;IronPython
URLs&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=a50f3ddf-941b-43ae-890a-532f527d2849" /&gt;</description><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://devhawk.net/Trackback.aspx?guid=a50f3ddf-941b-43ae-890a-532f527d2849</trackback:ping><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/pingback.aspx</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/PermaLink,guid,a50f3ddf-941b-43ae-890a-532f527d2849.aspx</pingback:target><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/CommentView,guid,a50f3ddf-941b-43ae-890a-532f527d2849.aspx</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/SyndicationService.asmx/GetEntryCommentsRss?guid=a50f3ddf-941b-43ae-890a-532f527d2849</wfw:commentRss><feedburner:origLink>http://devhawk.net/2008/08/29/Morning+Coffee+173.aspx</feedburner:origLink></item><item><title>Morning Coffee 172</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/374418593/Morning+Coffee+172.aspx</link><category>Development</category><category>F#</category><category>IronPython</category><category>IronRuby</category><category>Other/Family</category><category>Politics</category><category>Silverlight</category><category>Web 2.0</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Harry Pierson</dc:creator><pubDate>Mon, 25 Aug 2008 11:56:01 -0500</pubDate><guid isPermaLink="false">http://devhawk.net/PermaLink,guid,1446b623-c799-4f44-9cf7-a69fd666ca26.aspx</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
        <ul>
          <li>
I took the kids to see <a href="http://www.flymetothemoonthemovie.com/">Fly Me To
The Moon</a> recently. We had to trek to Monroe (about 30 minutes away) because it's
a special 3D movie, and it was only playing there and in downtown Seattle. The movie's
story is insipid - three flies stow away on Apollo 11 - but all the space shots were
actually kinda cool. It sure felt like they wanted to be scientifically and historically
accurate about the the actual mission (well, other than the part about the flies).
Patrick really liked it (he wants to build a rocket in the back yard) and Riley sat
thru the whole thing with a minimum of fussing. 
</li>
          <li>
I'm a big fan of Joe Biden, so I'm really happy Obama <a href="http://www.msnbc.msn.com/id/26365828/">picked
him</a> to be his running mate. 
</li>
          <li>
I know it's old news but what the frak was John Edwards thinking? I like his policies,
but the arrogance it takes to run for president when you know you've got that skeleton
in your closet is mind-boggling. 
</li>
          <li>
On the other hand, watching the Sean Hannity and guest's hypocrisy on Edwards' affair,
only to watch them <a href="http://www.youtube.com/watch?v=Da4N-CTTRIM">scramble like
cockroaches</a> when Colmes points out McCain had admitted to having an affair was
frakking hilarious. 
</li>
        </ul>
        <p>
OK, onto geek stuff: 
</p>
        <ul>
          <li>
My new boss Dave Remy has moved to a <a href="http://blog.remlog.net/">new blog</a>.
If you're curious what he was up to for the 10 months he was away from Microsoft,
he's <a href="http://blog.remlog.net/?p=4">happy to share</a>. 
</li>
          <li>
IPy and IRuby developer Curt Hagenlocher (aka Iron Curt) is <a href="http://blogs.msdn.com/curth/">blogging</a>.
Cue the Ozzy...I AM IRON CURT. Or don't. Anyway, he dives in the deep end of the pool
- no "hello world" lollyblogging for Iron Curt - digging into the <a href="http://blogs.msdn.com/curth/archive/2008/07/29/stackoverflowexception-and-ironpython.aspx">stack
implications of rethrowing exceptions</a> and <a href="http://blogs.msdn.com/curth/archive/2008/08/12/viewing-emitted-il.aspx">debugging
emitted IL</a>. 
</li>
          <li>
Srivatsn writes about <a href="http://blogs.msdn.com/srivatsn/archive/2008/08/06/static-compilation-of-ironpython-scripts.aspx">static
compilation of IPy scripts</a>. Note, we're not talking about static typing - it's
still the same good-old dynamically typed IronPython, just packaged up as an assembly,
rather than as a bunch of .py files. Note, if you're interested in compiling IronPython,
you should check out the PYC sample we published as part of <a href="http://www.codeplex.com/IronPython/Release/ProjectReleases.aspx?ReleaseId=14353">Beta
4</a>. 
</li>
          <li>
Speaking of IPy Beta 4, Shri Borde posts about the <a href="http://blogs.msdn.com/shrib/archive/2008/07/30/idispatch-support-on-in-ironpython-beta-4.aspx">COM
dispatch support</a> which is enabled by default as of Beta 4. If you're driving COM
automation clients (like Office) from IPy, this is a huge improvement over the old
mechanism. 
</li>
          <li>
Jeff Hardy has released a new version of NWSGI, a managed version of Python's <a href="http://www.python.org/dev/peps/pep-0333/">Web <strike>Service</strike> Server
Gateway Interface</a>. My understanding is that this would allow any Python web stack
written against WSGI to run in IIS with IronPython (subject to IronPython's compatibility
with CPython). Jeff's been <a href="http://jdhardy.blogspot.com/">documenting</a> his
efforts getting Django running with NWSGI on his blog. Awesome work Jeff! (Thanks
for the correction Seo!) 
</li>
          <li>
I <a href="http://devhawk.net/2006/03/08/The+SoCalled+Attention+Economy.aspx">never
really bought into</a> the "Attention Economy", but Chris Anderson's <a href="http://www.longtail.com/the_long_tail/2008/08/i-wish-people-w.html">economic
analysis</a> of his DIY Drones site traffic was fascinating. 
</li>
          <li>
Lutz announces "<a href="http://blog.lutzroeder.com/2008/08/future-of-net-reflector.html">it
is time to move on</a>" from Reflector and there was a collective horrified scream
in the .NET community. He's handing it over to Red Gate, who <a href="http://www.simple-talk.com/opinion/opinion-pieces/the-future-of-reflector-/">promised</a> they
"will continue to offer the tool for free to the community". 
</li>
          <li>
I missed this when he posted it in June, but I really liked Nikhil Kothari <a href="http://www.nikhilk.net/ViewModel-Pattern-DLR.aspx">use
of the DLR</a> in Silverlight to cut down on the XAML verbosity in his ViewModel action
binding. 
</li>
          <li>
Brian McNamara previews the new <a href="http://lorgonblog.spaces.live.com/Blog/cns!701679AD17B6D310!307.entry">Add
Reference</a> and <a href="http://lorgonblog.spaces.live.com/Blog/cns!701679AD17B6D310!347.entry">file
ordering</a> support in the upcoming F# CTP. I'm really looking forward to the project-to-project
reference support. I can't tell you how many times I've gotten burned because my main
project recompiled but my test project didn't. You just get used to hitting Rebuild
All instead of Build. As for file ordering, it's a bit of a bummer that F# requires
it, but the new experience is hella better than editing the project file by hand.
I'm <em>really </em>looking forward to the new CTP. 
</li>
        </ul>
        <img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=1446b623-c799-4f44-9cf7-a69fd666ca26"></img>
      <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Devhawk?a=Q3kUDK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=Q3kUDK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=z7Pr1K"><img src="http://feeds.feedburner.com/~f/Devhawk?i=z7Pr1K" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=XFBtrK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=XFBtrK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=lS47rk"><img src="http://feeds.feedburner.com/~f/Devhawk?i=lS47rk" border="0"></img></a>
</div>]]></content:encoded><description>&lt;ul&gt;
&lt;li&gt;
I took the kids to see &lt;a href="http://www.flymetothemoonthemovie.com/"&gt;Fly Me To
The Moon&lt;/a&gt; recently. We had to trek to Monroe (about 30 minutes away) because it's
a special 3D movie, and it was only playing there and in downtown Seattle. The movie's
story is insipid - three flies stow away on Apollo 11 - but all the space shots were
actually kinda cool. It sure felt like they wanted to be scientifically and historically
accurate about the the actual mission (well, other than the part about the flies).
Patrick really liked it (he wants to build a rocket in the back yard) and Riley sat
thru the whole thing with a minimum of fussing. 
&lt;li&gt;
I'm a big fan of Joe Biden, so I'm really happy Obama &lt;a href="http://www.msnbc.msn.com/id/26365828/"&gt;picked
him&lt;/a&gt; to be his running mate. 
&lt;li&gt;
I know it's old news but what the frak was John Edwards thinking? I like his policies,
but the arrogance it takes to run for president when you know you've got that skeleton
in your closet is mind-boggling. 
&lt;li&gt;
On the other hand, watching the Sean Hannity and guest's hypocrisy on Edwards' affair,
only to watch them &lt;a href="http://www.youtube.com/watch?v=Da4N-CTTRIM"&gt;scramble like
cockroaches&lt;/a&gt; when Colmes points out McCain had admitted to having an affair was
frakking hilarious. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
OK, onto geek stuff: 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
My new boss Dave Remy has moved to a &lt;a href="http://blog.remlog.net/"&gt;new blog&lt;/a&gt;.
If you're curious what he was up to for the 10 months he was away from Microsoft,
he's &lt;a href="http://blog.remlog.net/?p=4"&gt;happy to share&lt;/a&gt;. 
&lt;li&gt;
IPy and IRuby developer Curt Hagenlocher (aka Iron Curt) is &lt;a href="http://blogs.msdn.com/curth/"&gt;blogging&lt;/a&gt;.
Cue the Ozzy...I AM IRON CURT. Or don't. Anyway, he dives in the deep end of the pool
- no "hello world" lollyblogging for Iron Curt - digging into the &lt;a href="http://blogs.msdn.com/curth/archive/2008/07/29/stackoverflowexception-and-ironpython.aspx"&gt;stack
implications of rethrowing exceptions&lt;/a&gt; and &lt;a href="http://blogs.msdn.com/curth/archive/2008/08/12/viewing-emitted-il.aspx"&gt;debugging
emitted IL&lt;/a&gt;. 
&lt;li&gt;
Srivatsn writes about &lt;a href="http://blogs.msdn.com/srivatsn/archive/2008/08/06/static-compilation-of-ironpython-scripts.aspx"&gt;static
compilation of IPy scripts&lt;/a&gt;. Note, we're not talking about static typing - it's
still the same good-old dynamically typed IronPython, just packaged up as an assembly,
rather than as a bunch of .py files. Note, if you're interested in compiling IronPython,
you should check out the PYC sample we published as part of &lt;a href="http://www.codeplex.com/IronPython/Release/ProjectReleases.aspx?ReleaseId=14353"&gt;Beta
4&lt;/a&gt;. 
&lt;li&gt;
Speaking of IPy Beta 4, Shri Borde posts about the &lt;a href="http://blogs.msdn.com/shrib/archive/2008/07/30/idispatch-support-on-in-ironpython-beta-4.aspx"&gt;COM
dispatch support&lt;/a&gt; which is enabled by default as of Beta 4. If you're driving COM
automation clients (like Office) from IPy, this is a huge improvement over the old
mechanism. 
&lt;li&gt;
Jeff Hardy has released a new version of NWSGI, a managed version of Python's &lt;a href="http://www.python.org/dev/peps/pep-0333/"&gt;Web &lt;strike&gt;Service&lt;/strike&gt; Server
Gateway Interface&lt;/a&gt;. My understanding is that this would allow any Python web stack
written against WSGI to run in IIS with IronPython (subject to IronPython's compatibility
with CPython). Jeff's been &lt;a href="http://jdhardy.blogspot.com/"&gt;documenting&lt;/a&gt; his
efforts getting Django running with NWSGI on his blog. Awesome work Jeff! (Thanks
for the correction Seo!) 
&lt;li&gt;
I &lt;a href="http://devhawk.net/2006/03/08/The+SoCalled+Attention+Economy.aspx"&gt;never
really bought into&lt;/a&gt; the "Attention Economy", but Chris Anderson's &lt;a href="http://www.longtail.com/the_long_tail/2008/08/i-wish-people-w.html"&gt;economic
analysis&lt;/a&gt; of his DIY Drones site traffic was fascinating. 
&lt;li&gt;
Lutz announces "&lt;a href="http://blog.lutzroeder.com/2008/08/future-of-net-reflector.html"&gt;it
is time to move on&lt;/a&gt;" from Reflector and there was a collective horrified scream
in the .NET community. He's handing it over to Red Gate, who &lt;a href="http://www.simple-talk.com/opinion/opinion-pieces/the-future-of-reflector-/"&gt;promised&lt;/a&gt; they
"will continue to offer the tool for free to the community". 
&lt;li&gt;
I missed this when he posted it in June, but I really liked Nikhil Kothari &lt;a href="http://www.nikhilk.net/ViewModel-Pattern-DLR.aspx"&gt;use
of the DLR&lt;/a&gt; in Silverlight to cut down on the XAML verbosity in his ViewModel action
binding. 
&lt;li&gt;
Brian McNamara previews the new &lt;a href="http://lorgonblog.spaces.live.com/Blog/cns!701679AD17B6D310!307.entry"&gt;Add
Reference&lt;/a&gt; and &lt;a href="http://lorgonblog.spaces.live.com/Blog/cns!701679AD17B6D310!347.entry"&gt;file
ordering&lt;/a&gt; support in the upcoming F# CTP. I'm really looking forward to the project-to-project
reference support. I can't tell you how many times I've gotten burned because my main
project recompiled but my test project didn't. You just get used to hitting Rebuild
All instead of Build. As for file ordering, it's a bit of a bummer that F# requires
it, but the new experience is hella better than editing the project file by hand.
I'm &lt;em&gt;really &lt;/em&gt;looking forward to the new CTP. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=1446b623-c799-4f44-9cf7-a69fd666ca26" /&gt;</description><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://devhawk.net/Trackback.aspx?guid=1446b623-c799-4f44-9cf7-a69fd666ca26</trackback:ping><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/pingback.aspx</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/PermaLink,guid,1446b623-c799-4f44-9cf7-a69fd666ca26.aspx</pingback:target><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/CommentView,guid,1446b623-c799-4f44-9cf7-a69fd666ca26.aspx</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/SyndicationService.asmx/GetEntryCommentsRss?guid=1446b623-c799-4f44-9cf7-a69fd666ca26</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">1</slash:comments><feedburner:origLink>http://devhawk.net/2008/08/25/Morning+Coffee+172.aspx</feedburner:origLink></item><item><title>Links for 2008-08-21 [del.icio.us]</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/371570272/harrypierson</link><pubDate>Fri, 22 Aug 2008 00:00:00 -0500</pubDate><guid isPermaLink="false">http://del.icio.us/harrypierson#2008-08-21</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<ul>
<li><a href="http://photosynth.net/">Photosynth</a></li>
</ul>]]></content:encoded><description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://photosynth.net/"&gt;Photosynth&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><feedburner:origLink>http://del.icio.us/harrypierson#2008-08-21</feedburner:origLink></item><item><title>Missing Missing Persons</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/369198067/Missing+Missing+Persons.aspx</link><category>Microsoft</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Harry Pierson</dc:creator><pubDate>Tue, 19 Aug 2008 12:14:31 -0500</pubDate><guid isPermaLink="false">http://devhawk.net/PermaLink,guid,d7cb17a3-d9f6-44a0-995e-50187201a6b8.aspx</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
        <p>
I'm having a hard time focusing on work today. I just found out that a good friend
and ex-teammate Robert Satterwhite <a href="http://www.legacy.com/Tribnet/DeathNotices.asp?Page=LifeStory&amp;PersonId=115888841">passed
away last week</a>. 
</p>
        <p>
I spent a year on the .NET Adoption Team with Robert back in 2002 &amp; 2003 - basically
my last year in the Microsoft field organization. NAT - as were were known - was a
national team of developer and architecture evangelists, so while we were all teammates,
we didn't see much of each other in person. However, Rob and I both lived in the Puget
Sound area and called on many of the same customers - I was an architect evangelist
and Robert was a developer evangelist - so we ended up working together often. We
drove together to Olympia many times- he drove and I hacked code in a kind of strange
pair programming effort.
</p>
        <p>
Robert grew up in the Pacific NW and had spent almost his entire career as an enterprise
technology sales engineer here, so he had friends everywhere. I often used the lame
line from the <a href="http://www.imdb.com/title/tt0092925/">Dragnet movie</a> with
Dan Aykroyd: "They ought to put you in Missing Persons. You know everybody." because
it seemed like everywhere we went we'd run into someone he grew up with, had worked
with or had sold to. If we hung around before or after a sales call - coffee shop
in Olympia before a meeting, debriefing with the sales rep on the steps outside of
Costco HQ in Issaquah, etc - chances are someone would recognize him. 
</p>
        <p>
When I was leaving the NAT, Robert and I went to Phoenix so I could hand off my customers
there to him. I joked that at least I could be sure we wouldn't run into anyone he
knew in Arizona. Yet, it turned out he used to work with the woman who was sitting
in front of him on the flight home. She and her husband owned car dealerships in Phoenix
and Tacoma. I was astonished - what are the frakking odds? - but Rob just shrugged
his shoulders. It happened to him all the time so I guess he was used to it.
</p>
        <p>
I only saw him off and on since I left the team, though as fate would have it I did
see him last week on the day he died. I was heading into building 18 for a meeting
as he was pulling into the parking lot - I hadn't realized he was working on campus.
We exchanged the usual pleasantries and promised that we'd get together soon. He was
blocking traffic, so it was a short conversation. 24 hours later, he was dead. 
</p>
        <p>
Rob wasn't your prototypical <a href="http://blogs.msdn.com/stevecla01/archive/2006/10/31/microsoft-change-the-world-or-go-home.aspx">blue
monster</a>, but he sure touched a lot of people and he made the world a better place
by just being himself. You will be missed, Rob.
</p>
        <img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=d7cb17a3-d9f6-44a0-995e-50187201a6b8"></img>
      <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Devhawk?a=f1gjFK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=f1gjFK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=GGoPiK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=GGoPiK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=t2O8RK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=t2O8RK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=VPGbQk"><img src="http://feeds.feedburner.com/~f/Devhawk?i=VPGbQk" border="0"></img></a>
</div>]]></content:encoded><description>&lt;p&gt;
I'm having a hard time focusing on work today. I just found out that a good friend
and ex-teammate Robert Satterwhite &lt;a href="http://www.legacy.com/Tribnet/DeathNotices.asp?Page=LifeStory&amp;amp;PersonId=115888841"&gt;passed
away last week&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
I spent a year on the .NET Adoption Team with Robert back in 2002 &amp;amp; 2003 - basically
my last year in the Microsoft field organization. NAT - as were were known - was a
national team of developer and architecture evangelists, so while we were all teammates,
we didn't see much of each other in person. However, Rob and I both lived in the Puget
Sound area and called on many of the same customers - I was an architect evangelist
and Robert was a developer evangelist - so we ended up working together often. We
drove together to Olympia many times- he drove and I hacked code in a kind of strange
pair programming effort.
&lt;/p&gt;
&lt;p&gt;
Robert grew up in the Pacific NW and had spent almost his entire career as an enterprise
technology sales engineer here, so he had friends everywhere. I often used the lame
line from the &lt;a href="http://www.imdb.com/title/tt0092925/"&gt;Dragnet movie&lt;/a&gt; with
Dan Aykroyd: "They ought to put you in Missing Persons. You know everybody." because
it seemed like everywhere we went we'd run into someone he grew up with, had worked
with or had sold to. If we hung around before or after a sales call - coffee shop
in Olympia before a meeting, debriefing with the sales rep on the steps outside of
Costco HQ in Issaquah, etc - chances are someone would recognize him. 
&lt;/p&gt;
&lt;p&gt;
When I was leaving the NAT, Robert and I went to Phoenix so I could hand off my customers
there to him. I joked that at least I could be sure we wouldn't run into anyone he
knew in Arizona. Yet, it turned out he used to work with the woman who was sitting
in front of him on the flight home. She and her husband owned car dealerships in Phoenix
and Tacoma. I was astonished - what are the frakking odds? - but Rob just shrugged
his shoulders. It happened to him all the time so I guess he was used to it.
&lt;/p&gt;
&lt;p&gt;
I only saw him off and on since I left the team, though as fate would have it I did
see him last week on the day he died. I was heading into building 18 for a meeting
as he was pulling into the parking lot - I hadn't realized he was working on campus.
We exchanged the usual pleasantries and promised that we'd get together soon. He was
blocking traffic, so it was a short conversation. 24 hours later, he was dead. 
&lt;/p&gt;
&lt;p&gt;
Rob wasn't your prototypical &lt;a href="http://blogs.msdn.com/stevecla01/archive/2006/10/31/microsoft-change-the-world-or-go-home.aspx"&gt;blue
monster&lt;/a&gt;, but he sure touched a lot of people and he made the world a better place
by just being himself. You will be missed, Rob.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=d7cb17a3-d9f6-44a0-995e-50187201a6b8" /&gt;</description><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://devhawk.net/Trackback.aspx?guid=d7cb17a3-d9f6-44a0-995e-50187201a6b8</trackback:ping><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/pingback.aspx</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/PermaLink,guid,d7cb17a3-d9f6-44a0-995e-50187201a6b8.aspx</pingback:target><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/CommentView,guid,d7cb17a3-d9f6-44a0-995e-50187201a6b8.aspx</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/SyndicationService.asmx/GetEntryCommentsRss?guid=d7cb17a3-d9f6-44a0-995e-50187201a6b8</wfw:commentRss><feedburner:origLink>http://devhawk.net/2008/08/19/Missing+Missing+Persons.aspx</feedburner:origLink></item><item><title>Links for 2008-08-17 [del.icio.us]</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/367797920/harrypierson</link><pubDate>Mon, 18 Aug 2008 00:00:00 -0500</pubDate><guid isPermaLink="false">http://del.icio.us/harrypierson#2008-08-17</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<ul>
<li><a href="http://www.frys-electronics-ads.com/">Fry's Electronics Ad</a><br/>
Lists current ads, specials and sales at Fry&#039;s Electronics, including computers, notebooks, memories, hard drives, DVD Players, Digital Cameras, PDAs, printers, etc.</li>
</ul>]]></content:encoded><description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.frys-electronics-ads.com/"&gt;Fry's Electronics Ad&lt;/a&gt;&lt;br/&gt;
Lists current ads, specials and sales at Fry&amp;#039;s Electronics, including computers, notebooks, memories, hard drives, DVD Players, Digital Cameras, PDAs, printers, etc.&lt;/li&gt;
&lt;/ul&gt;</description><feedburner:origLink>http://del.icio.us/harrypierson#2008-08-17</feedburner:origLink></item><item><title>Links for 2008-08-14 [del.icio.us]</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/365393224/harrypierson</link><pubDate>Fri, 15 Aug 2008 00:00:00 -0500</pubDate><guid isPermaLink="false">http://del.icio.us/harrypierson#2008-08-14</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<ul>
<li><a href="http://www.bolour.com/papers/monads-through-pictures.html">Monads through Pictures</a><br/>
Monads in functional programming provide a framework for aspect-aware computations to be composed to build higher-level aspect-aware computations.</li>
</ul>]]></content:encoded><description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.bolour.com/papers/monads-through-pictures.html"&gt;Monads through Pictures&lt;/a&gt;&lt;br/&gt;
Monads in functional programming provide a framework for aspect-aware computations to be composed to build higher-level aspect-aware computations.&lt;/li&gt;
&lt;/ul&gt;</description><feedburner:origLink>http://del.icio.us/harrypierson#2008-08-14</feedburner:origLink></item><item><title>Monadic Philosophy Part 5 - Reader Comments</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/359891552/Monadic+Philosophy+Part+5+Reader+Comments.aspx</link><category>C#</category><category>F#</category><category>Functional Programming</category><category>Monads</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Harry Pierson</dc:creator><pubDate>Fri, 08 Aug 2008 19:20:06 -0500</pubDate><guid isPermaLink="false">http://devhawk.net/PermaLink,guid,c7d7d1db-0c17-4845-b30f-0fbed21e5741.aspx</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
        <p>
          <a href="http://barrkel.blogspot.com/">Barry Kelly</a> <a href="http://devhawk.net/CommentView,guid,6ce19647-2f6f-4d41-aff6-b202df528d21.aspx#commentstart">thinks</a> that
"programmers would understand monads better if they were described as a design pattern".
I agree 100% and would love to see a monad design pattern written out using p&amp;p's <a href="http://msdn.microsoft.com/en-us/library/ms979209.aspx">pattern
form</a>. The one thing I would note on this is that certain language constructs can
make working with certain design patterns easier. For example, C# obviously has great
language level support for the <a href="http://en.wikipedia.org/wiki/Iterator_pattern">Iterator
design pattern</a>. Once you've got language level support, it doesn't really feel
like a design pattern anymore, it feels like a language feature. I mean, given that
you can write OO code in a language like C, does that mean technically OO is a "design
pattern". I don't think so. 
</p>
        <p>
A commenter named atp <a href="http://devhawk.net/CommentView,guid,6ce19647-2f6f-4d41-aff6-b202df528d21.aspx#commentstart">warned
me</a> not to "fall into the newbie trap of thinking that monads are about sequencing
operations. They aren't. A large number of monads (for example, Reader) are commutative
and do not enforce any sort of statement ordering." Fair enough. For example, you
switch the order of some LINQ operators and still end up with the same result. If
you switch Where and Select, you should end up with the same output (assuming the
where clause isn't invalidated by the select projection). But from a C#/F# perspective,
I don't really care about monads for enforcing order anyway - the language has that
natively. I care much more about the context flow aspect of monads, which it sounds
like atp thinks we should be focused on anyway. Works for me. 
</p>
        <p>
Finally, <a href="http://elder_george.livejournal.com">Yuri K.</a> <a href="http://devhawk.net/CommentView,guid,f0fb5461-eb30-4268-a4b3-7262276768cb.aspx#commentstart">pointed
out</a> that we aren't really stuck with the nested lambda expression syntax in C#.
In Luke Hoban's <a href="http://blogs.msdn.com/lukeh/archive/2007/08/19/monadic-parser-combinators-using-c-3-0.aspx">Monadic
Parser Combinators using C# 3.0</a> post, he implements a Where, Select and SelectMany
extension method for his Parser delegate type, which allows him to plug into C#'s
query comprehension syntax. He's 100% correct and I considered including this fact
in my post. However, the mapping between query comprehension and the Bind and Result
functions is a little murky, so I skipped it. 
</p>
        <p>
For C# query comprehensions, basically SelectMany does double duty, not only binding
the parser and the parser generating function (which Luke called 'selector'), but
also taking the two parse values and calling to a projector function and returning
the projection return value in a Result. By implementing SelectMany, you can rewrite
the TwoValues parser like this:
</p>
        <div style="font-family: consolas,lucida console,courier new">
          <span style="color: blue">static</span> Parser&lt;<span style="color: blue">string</span>&gt;
QueryTwoItems()  
<br>
{  
<br>
    <span style="color: blue">return</span> <span style="color: blue">from</span> v1 <span style="color: blue">in</span> Item()   
<br>
           <span style="color: blue">from</span> v2 <span style="color: blue">in</span> Item()   
<br>
           <span style="color: blue">select</span> <span style="color: blue">string</span>.Format(<span style="color: maroon">"{0}{1}"</span>,
v1, v2);  
<br>
}
</div>
        <p>
which looks pretty much identical to the F# monadic syntax version. Luke also implements
Where, which I have in my F# parser library as Satisfy. Where takes a parser and only
returns the parser result if the provided boolean predicate returns true. Select is
a projection, similar to SelectMany but only used with a single parser. I have a couple
of specific projectors in my F# library (Ignore which tosses the parse result and
Listify which turns a single result into a single item list) but I haven't had any
need for a generic projector like Select. I'm assuming Luke only implemented Select
to make the query comprehension work when you don't have multiple from statements. 
</p>
        <img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=c7d7d1db-0c17-4845-b30f-0fbed21e5741"></img>
      <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Devhawk?a=G1U8cK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=G1U8cK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=EsuXwK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=EsuXwK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=sXQjFK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=sXQjFK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=sUITyk"><img src="http://feeds.feedburner.com/~f/Devhawk?i=sUITyk" border="0"></img></a>
</div>]]></content:encoded><description>&lt;p&gt;
&lt;a href="http://barrkel.blogspot.com/"&gt;Barry Kelly&lt;/a&gt;&amp;nbsp;&lt;a href="http://devhawk.net/CommentView,guid,6ce19647-2f6f-4d41-aff6-b202df528d21.aspx#commentstart"&gt;thinks&lt;/a&gt; that
"programmers would understand monads better if they were described as a design pattern".
I agree 100% and would love to see a monad design pattern written out using p&amp;amp;p's &lt;a href="http://msdn.microsoft.com/en-us/library/ms979209.aspx"&gt;pattern
form&lt;/a&gt;. The one thing I would note on this is that certain language constructs can
make working with certain design patterns easier. For example, C# obviously has great
language level support for the &lt;a href="http://en.wikipedia.org/wiki/Iterator_pattern"&gt;Iterator
design pattern&lt;/a&gt;. Once you've got language level support, it doesn't really feel
like a design pattern anymore, it feels like a language feature. I mean, given that
you can write OO code in a language like C, does that mean technically OO is a "design
pattern". I don't think so. 
&lt;/p&gt;
&lt;p&gt;
A commenter named atp &lt;a href="http://devhawk.net/CommentView,guid,6ce19647-2f6f-4d41-aff6-b202df528d21.aspx#commentstart"&gt;warned
me&lt;/a&gt; not to "fall into the newbie trap of thinking that monads are about sequencing
operations. They aren't. A large number of monads (for example, Reader) are commutative
and do not enforce any sort of statement ordering." Fair enough. For example, you
switch the order of some LINQ operators and still end up with the same result. If
you switch Where and Select, you should end up with the same output (assuming the
where clause isn't invalidated by the select projection). But from a C#/F# perspective,
I don't really care about monads for enforcing order anyway - the language has that
natively. I care much more about the context flow aspect of monads, which it sounds
like atp thinks we should be focused on anyway. Works for me. 
&lt;/p&gt;
&lt;p&gt;
Finally, &lt;a href="http://elder_george.livejournal.com"&gt;Yuri K.&lt;/a&gt;&amp;nbsp;&lt;a href="http://devhawk.net/CommentView,guid,f0fb5461-eb30-4268-a4b3-7262276768cb.aspx#commentstart"&gt;pointed
out&lt;/a&gt; that we aren't really stuck with the nested lambda expression syntax in C#.
In Luke Hoban's &lt;a href="http://blogs.msdn.com/lukeh/archive/2007/08/19/monadic-parser-combinators-using-c-3-0.aspx"&gt;Monadic
Parser Combinators using C# 3.0&lt;/a&gt; post, he implements a Where, Select and SelectMany
extension method for his Parser delegate type, which allows him to plug into C#'s
query comprehension syntax. He's 100% correct and I considered including this fact
in my post. However, the mapping between query comprehension and the Bind and Result
functions is a little murky, so I skipped it. 
&lt;/p&gt;
&lt;p&gt;
For C# query comprehensions, basically SelectMany does double duty, not only binding
the parser and the parser generating function (which Luke called 'selector'), but
also taking the two parse values and calling to a projector function and returning
the projection return value in a Result. By implementing SelectMany, you can rewrite
the TwoValues parser like this:
&lt;/p&gt;
&lt;div style="font-family: consolas,lucida console,courier new"&gt;&lt;span style="color: blue"&gt;static&lt;/span&gt; Parser&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt;
QueryTwoItems()&amp;nbsp; 
&lt;br&gt;
{&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue"&gt;from&lt;/span&gt; v1 &lt;span style="color: blue"&gt;in&lt;/span&gt; Item()&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;from&lt;/span&gt; v2 &lt;span style="color: blue"&gt;in&lt;/span&gt; Item()&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;select&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: maroon"&gt;"{0}{1}"&lt;/span&gt;,
v1, v2);&amp;nbsp; 
&lt;br&gt;
}
&lt;/div&gt;
&lt;p&gt;
which looks pretty much identical to the F# monadic syntax version. Luke also implements
Where, which I have in my F# parser library as Satisfy. Where takes a parser and only
returns the parser result if the provided boolean predicate returns true. Select is
a projection, similar to SelectMany but only used with a single parser. I have a couple
of specific projectors in my F# library (Ignore which tosses the parse result and
Listify which turns a single result into a single item list) but I haven't had any
need for a generic projector like Select. I'm assuming Luke only implemented Select
to make the query comprehension work when you don't have multiple from statements. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=c7d7d1db-0c17-4845-b30f-0fbed21e5741" /&gt;</description><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://devhawk.net/Trackback.aspx?guid=c7d7d1db-0c17-4845-b30f-0fbed21e5741</trackback:ping><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/pingback.aspx</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/PermaLink,guid,c7d7d1db-0c17-4845-b30f-0fbed21e5741.aspx</pingback:target><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/CommentView,guid,c7d7d1db-0c17-4845-b30f-0fbed21e5741.aspx</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/SyndicationService.asmx/GetEntryCommentsRss?guid=c7d7d1db-0c17-4845-b30f-0fbed21e5741</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">1</slash:comments><feedburner:origLink>http://devhawk.net/2008/08/09/Monadic+Philosophy+Part+5+Reader+Comments.aspx</feedburner:origLink></item><item><title>Nobody Cares That I Called McCain a Dick?</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/359743933/Nobody+Cares+That+I+Called+McCain+A+Dick.aspx</link><category>Politics</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Harry Pierson</dc:creator><pubDate>Fri, 08 Aug 2008 15:42:44 -0500</pubDate><guid isPermaLink="false">http://devhawk.net/PermaLink,guid,bec9c96a-0cd2-49f8-a322-af9cb882073f.aspx</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
        <p>
In Febuary, <a href="http://devhawk.net/2008/02/11/Morning+Coffee+145.aspx">when I
said</a> "Romney's a real douche bag", <a href="http://devhawk.net/CommentView,guid,d88e8506-d669-41c3-a246-6da1865f9a2e.aspx#commentstart">several
upset commenters</a> vowed never to read my blog again. I was even called a bigot
(though <a href="http://halfmybrain.spaces.live.com/">Dale</a> jumped in and explained
how wrong a charge that is). Frankly, anytime I run a political post, especially ones
where I call prominent Republicans names, that's the reaction I expect. 
</p>
        <p>
So it kinda surprised me that the <a href="http://devhawk.net/CommentView,guid,be8c3c37-012b-499f-a1d2-1db86c5771b5.aspx#commentstart">response</a> to <a href="http://devhawk.net/2008/08/01/McCains+Dick+Move+Of+The+Week.aspx">calling
McCain a dick and his campaign an embarrassment</a> was so tepid. No outrage. No promises
to unsubscribe nor predictions that others would do likewise. Dale sounds like he
agrees that McCain's campaign is an embarrassment, even though he clearly supports
McCain. RandyG doesn't have anything to say about McCain one way or the other, but
he thinks Obama is a "pompous dick". Only BigJ provides any defense of McCain at all,
but it's an extremely weak defense. He described McCain as "not afraid to tick off
a powerful, influential, big money contributor", which I would expect is hard to say
out loud with a straight face. Given that McCain <a href="http://www.washingtonpost.com/wp-dyn/content/article/2008/07/26/AR2008072601891_pf.html">has
raked in millions in contributions from the oil industry</a> after flip-flopping on
offshore drilling, describing the Hilton's $4,600 contribution as "powerful, influential,
big money" is laughable. Hell, McCain is returning <a href="http://thecaucus.blogs.nytimes.com/2008/08/07/mccain-campaign-is-reviewing-donations/">ten
times that amount</a> in "unusual" (read: possibly illegal) contributions because
they "just didn’t sound right". 
</p>
        <p>
I figure there are two main possible reasons for the lack of outrage:
</p>
        <ul>
          <li>
All my readers who are willing to unsubscribe because I don't agree with their political
view have already left, leaving only those who agree with or simply ignore my political
posts.</li>
          <li>
The number of people willing to stand up and defend McCain, even anonymously in my
small corner of the Internet, is very small.</li>
        </ul>
        <p>
Personally, I probably a little of both, but I'm guessing it's more the latter than
the former. 
</p>
        <img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=bec9c96a-0cd2-49f8-a322-af9cb882073f"></img>
      <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Devhawk?a=ZSgQsK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=ZSgQsK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=w4SMqK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=w4SMqK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=nUgyMK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=nUgyMK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=4Xf9ck"><img src="http://feeds.feedburner.com/~f/Devhawk?i=4Xf9ck" border="0"></img></a>
</div>]]></content:encoded><description>&lt;p&gt;
In Febuary, &lt;a href="http://devhawk.net/2008/02/11/Morning+Coffee+145.aspx"&gt;when I
said&lt;/a&gt; "Romney's a real douche bag", &lt;a href="http://devhawk.net/CommentView,guid,d88e8506-d669-41c3-a246-6da1865f9a2e.aspx#commentstart"&gt;several
upset commenters&lt;/a&gt; vowed never to read my blog again. I was even called a bigot
(though &lt;a href="http://halfmybrain.spaces.live.com/"&gt;Dale&lt;/a&gt; jumped in and explained
how wrong a charge that is). Frankly, anytime I run a political post, especially ones
where I call prominent Republicans names, that's the reaction I expect. 
&lt;/p&gt;
&lt;p&gt;
So it kinda surprised me that the &lt;a href="http://devhawk.net/CommentView,guid,be8c3c37-012b-499f-a1d2-1db86c5771b5.aspx#commentstart"&gt;response&lt;/a&gt; to &lt;a href="http://devhawk.net/2008/08/01/McCains+Dick+Move+Of+The+Week.aspx"&gt;calling
McCain a dick and his campaign an embarrassment&lt;/a&gt; was so tepid. No outrage. No promises
to unsubscribe nor predictions that others would do likewise. Dale sounds like he
agrees that McCain's campaign is an embarrassment, even though he clearly supports
McCain. RandyG doesn't have anything to say about McCain one way or the other, but
he thinks Obama is a "pompous dick". Only BigJ provides any defense of McCain at all,
but it's an extremely weak defense. He described McCain as "not afraid to tick off
a powerful, influential, big money contributor", which I would expect is hard to say
out loud with a straight face. Given that McCain &lt;a href="http://www.washingtonpost.com/wp-dyn/content/article/2008/07/26/AR2008072601891_pf.html"&gt;has
raked in millions in contributions from the oil industry&lt;/a&gt; after flip-flopping on
offshore drilling, describing the Hilton's $4,600 contribution as "powerful, influential,
big money" is laughable. Hell, McCain is returning &lt;a href="http://thecaucus.blogs.nytimes.com/2008/08/07/mccain-campaign-is-reviewing-donations/"&gt;ten
times that amount&lt;/a&gt; in "unusual" (read: possibly illegal) contributions because
they "just didn’t sound right". 
&lt;/p&gt;
&lt;p&gt;
I figure there are two main possible reasons for the lack of outrage:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
All my readers who are willing to unsubscribe because I don't agree with their political
view have already left, leaving only those who agree with or simply ignore my political
posts.&lt;/li&gt;
&lt;li&gt;
The number of people willing to stand up and defend McCain, even anonymously in my
small corner of the Internet, is very small.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Personally, I probably a little of both, but I'm guessing it's more the latter than
the former. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=bec9c96a-0cd2-49f8-a322-af9cb882073f" /&gt;</description><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://devhawk.net/Trackback.aspx?guid=bec9c96a-0cd2-49f8-a322-af9cb882073f</trackback:ping><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/pingback.aspx</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/PermaLink,guid,bec9c96a-0cd2-49f8-a322-af9cb882073f.aspx</pingback:target><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/CommentView,guid,bec9c96a-0cd2-49f8-a322-af9cb882073f.aspx</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/SyndicationService.asmx/GetEntryCommentsRss?guid=bec9c96a-0cd2-49f8-a322-af9cb882073f</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">6</slash:comments><feedburner:origLink>http://devhawk.net/2008/08/08/Nobody+Cares+That+I+Called+McCain+A+Dick.aspx</feedburner:origLink></item><item><title>Including the Batteries in IronPython</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/357470197/Including+The+Batteries+In+IronPython.aspx</link><category>IronPython</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Harry Pierson</dc:creator><pubDate>Wed, 06 Aug 2008 09:50:23 -0500</pubDate><guid isPermaLink="false">http://devhawk.net/PermaLink,guid,355828d2-3864-47f4-9baf-3abb037fcf1d.aspx</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
        <blockquote>
          <p>
Fans of Python use the phrase "batteries included" to describe the <a href="http://docs.python.org/lib/lib.html">standard
library</a>, which covers everything from asynchronous processing to zip files.<br><a href="http://www.python.org/about/">About Python</a></p>
        </blockquote>
        <p>
I'm very happy to announce that as of <a href="http://www.codeplex.com/IronPython/Release/ProjectReleases.aspx?ReleaseId=14353">IronPython
Beta 4</a>, we are including the Python standard library in an IronPython release.
In addition to the usual binary and source zip archives, we're shipping an MSI installer
that gives you the option to include the library files. I <a href="http://devhawk.net/2008/07/17/IronPython+Post+20+Roadmap.aspx">mentioned</a> a
couple of weeks ago that I've been spending a lot of time with lawyers, and this is
the first step towards making the IronPython project as open as possible. Note the
use of the word "first" in that previous statement. In other words, I've got more
lawyers to talk to.
</p>
        <p>
We've added a new standard library component category to the <a href="http://www.codeplex.com/IronPython/WorkItem/AdvancedList.aspx">IronPython
Issue Tracker</a>. So if you find any issues or incompatibilities with using the standard
library with IronPython, please files bugs on them. We haven't figured out what set
of libraries we're going to ship, but we don't want to include ones that we know wont
work. For example, Kevin Chu <a href="http://lists.ironpython.com/pipermail/users-ironpython.com/2008-August/007908.html">reported
on the mailing list</a> that importing the sqlite3 module fails. This is because we
don't have a managed version of the _sqlite3 C-based module. So that's one we'll probably
remove outright. 
</p>
        <p>
Also, this is the first release we've distributed as an MSI file, and it looks some
folks on the mailing list have had some troubles with it. If you have issues, please
file setup bugs as well.
</p>
        <img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=355828d2-3864-47f4-9baf-3abb037fcf1d"></img>
      <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Devhawk?a=9n6U7K"><img src="http://feeds.feedburner.com/~f/Devhawk?i=9n6U7K" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=auVxGK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=auVxGK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=Hq6rzK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=Hq6rzK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=9Whg2K"><img src="http://feeds.feedburner.com/~f/Devhawk?i=9Whg2K" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=thEBek"><img src="http://feeds.feedburner.com/~f/Devhawk?i=thEBek" border="0"></img></a>
</div>]]></content:encoded><description>&lt;blockquote&gt; 
&lt;p&gt;
Fans of Python use the phrase "batteries included" to describe the &lt;a href="http://docs.python.org/lib/lib.html"&gt;standard
library&lt;/a&gt;, which covers everything from asynchronous processing to zip files.&lt;br&gt;
&lt;a href="http://www.python.org/about/"&gt;About Python&lt;/a&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
I'm very happy to announce that as of &lt;a href="http://www.codeplex.com/IronPython/Release/ProjectReleases.aspx?ReleaseId=14353"&gt;IronPython
Beta 4&lt;/a&gt;, we are including the Python standard library in an IronPython release.
In addition to the usual binary and source zip archives, we're shipping an MSI installer
that gives you the option to include the library files. I &lt;a href="http://devhawk.net/2008/07/17/IronPython+Post+20+Roadmap.aspx"&gt;mentioned&lt;/a&gt; a
couple of weeks ago that I've been spending a lot of time with lawyers, and this is
the first step towards making the IronPython project as open as possible. Note the
use of the word "first" in that previous statement. In other words, I've got more
lawyers to talk to.
&lt;/p&gt;
&lt;p&gt;
We've added a new standard library component category to the &lt;a href="http://www.codeplex.com/IronPython/WorkItem/AdvancedList.aspx"&gt;IronPython
Issue Tracker&lt;/a&gt;. So if you find any issues or incompatibilities with using the standard
library with IronPython, please files bugs on them. We haven't figured out what set
of libraries we're going to ship, but we don't want to include ones that we know wont
work. For example, Kevin Chu &lt;a href="http://lists.ironpython.com/pipermail/users-ironpython.com/2008-August/007908.html"&gt;reported
on the mailing list&lt;/a&gt; that importing the sqlite3 module fails. This is because we
don't have a managed version of the _sqlite3 C-based module. So that's one we'll probably
remove outright. 
&lt;/p&gt;
&lt;p&gt;
Also, this is the first release we've distributed as an MSI file, and it looks some
folks on the mailing list have had some troubles with it. If you have issues, please
file setup bugs as well.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=355828d2-3864-47f4-9baf-3abb037fcf1d" /&gt;</description><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://devhawk.net/Trackback.aspx?guid=355828d2-3864-47f4-9baf-3abb037fcf1d</trackback:ping><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/pingback.aspx</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/PermaLink,guid,355828d2-3864-47f4-9baf-3abb037fcf1d.aspx</pingback:target><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/CommentView,guid,355828d2-3864-47f4-9baf-3abb037fcf1d.aspx</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/SyndicationService.asmx/GetEntryCommentsRss?guid=355828d2-3864-47f4-9baf-3abb037fcf1d</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">2</slash:comments><feedburner:origLink>http://devhawk.net/2008/08/06/Including+The+Batteries+In+IronPython.aspx</feedburner:origLink></item><item><title>Links for 2008-08-03 [del.icio.us]</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/354992310/harrypierson</link><pubDate>Mon, 04 Aug 2008 00:00:00 -0500</pubDate><guid isPermaLink="false">http://del.icio.us/harrypierson#2008-08-03</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<ul>
<li><a href="http://feeds.feedburner.com/planet_fsharp">Planet F#</a><br/>
An aggregate feed of F# links</li>
<li><a href="http://citeseer.ist.psu.edu/meijer91functional.html">Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire</a><br/>
We develop a calculus that is useful in deriving and manipulating lazy functional programs.</li>
</ul>]]></content:encoded><description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://feeds.feedburner.com/planet_fsharp"&gt;Planet F#&lt;/a&gt;&lt;br/&gt;
An aggregate feed of F# links&lt;/li&gt;
&lt;li&gt;&lt;a href="http://citeseer.ist.psu.edu/meijer91functional.html"&gt;Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire&lt;/a&gt;&lt;br/&gt;
We develop a calculus that is useful in deriving and manipulating lazy functional programs.&lt;/li&gt;
&lt;/ul&gt;</description><feedburner:origLink>http://del.icio.us/harrypierson#2008-08-03</feedburner:origLink></item><item><title>Monadic Philosophy Part 4 - The Parser Monad in F#</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/353074678/Monadic+Philosophy+Part+4+The+Parser+Monad+In+F.aspx</link><category>F#</category><category>Functional Programming</category><category>Monads</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Harry Pierson</dc:creator><pubDate>Fri, 01 Aug 2008 17:42:57 -0500</pubDate><guid isPermaLink="false">http://devhawk.net/PermaLink,guid,9b8f0a29-ba33-46a2-a34d-ab470fa5e59a.aspx</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
        <p>
In the <a href="http://devhawk.net/2008/08/01/Monadic+Philosophy+Part+3+The+Parser+Monad+In+C.aspx">last
post</a>, I built out a basic parser monad in C#. While the approach worked OK, the
syntax is still a little foreign to your typical .NET programmer, what with it's nested
anonymous functions and all. Now, I'm going to translate that code to F# and take
a look at the special monadic syntax F# supports that makes using monads as easy any
sequential code.
</p>
        <p>
First, let's translate our Parser delegate, Bind, Result and Item functions over to
F#. Just for kicks, let's also port over the final version of TwoItems too.
</p>
        <div style="font-family: consolas,lucida console,courier new">
          <span style="color: blue">type</span> Parser&lt;'input,
'result&gt; = 'input<span style="color: blue">-&gt;</span> <span style="color: blue">(</span>'result
* 'input<span style="color: blue">)</span> option 
<br><br><span style="color: green">// the Bind function, defined as a custom operator</span><br><span style="color: blue">let</span> <span style="color: blue">(</span>&gt;&gt;=<span style="color: blue">)</span> p
f <span style="color: blue">:</span> Parser&lt;'i,'r&gt; =  
<br>
    <span style="color: blue">fun</span> input <span style="color: blue">-&gt;</span><br>
        <span style="color: blue">match</span> p
input <span style="color: blue">with</span><br>
        <span style="color: blue">|</span> Some<span style="color: blue">(</span>value,
input<span style="color: blue">)</span> <span style="color: blue">-&gt;</span> <span style="color: blue">(</span>f
value<span style="color: blue">)</span> input 
<br>
        <span style="color: blue">|</span> None <span style="color: blue">-&gt;</span> None 
<br><br><span style="color: blue">let</span> Result v <span style="color: blue">:</span> Parser&lt;'i,'r&gt;
= <span style="color: blue">fun</span> input <span style="color: blue">-&gt;</span> Some<span style="color: blue">(</span>v,
input<span style="color: blue">)</span><br><br><span style="color: blue">let</span> Item <span style="color: blue">:</span> Parser&lt;<span style="color: blue">string</span>, <span style="color: blue">char</span>&gt;
=  
<br>
    <span style="color: blue">fun</span> input <span style="color: blue">-&gt;</span><br>
        <span style="color: blue">if</span> <span style="color: blue">string</span><span style="color: blue">.</span>IsNullOrEmpty<span style="color: blue">(</span>input<span style="color: blue">)</span>  
<br>
            <span style="color: blue">then</span> None 
<br>
            <span style="color: blue">else</span> Some<span style="color: blue">(</span>input<span style="color: blue">.</span><span style="color: blue">[</span><span style="color: maroon">0</span><span style="color: blue">]</span>,
input<span style="color: blue">.</span>Substring<span style="color: blue">(</span><span style="color: maroon">1</span><span style="color: blue">)</span><span style="color: blue">)</span><br><br><span style="color: blue">let</span> BestTwoItems =  
<br>
    Item &gt;&gt;= <span style="color: blue">(</span><span style="color: blue">fun</span> v1 <span style="color: blue">-&gt;</span>  
<br>
    Item &gt;&gt;= <span style="color: blue">(</span><span style="color: blue">fun</span> v2 <span style="color: blue">-&gt;</span>  
<br>
    Result <span style="color: blue">(</span>sprintf <span style="color: maroon">"%c%c"</span> v1
v2<span style="color: blue">)</span><span style="color: blue">)</span><span style="color: blue">)</span></div>
        <p>
First, we start with the declaration of the Parser type. Unlike C#, F# has built in
support for tuples, so I didn't bother to define a Result type (just the Result function).
A Parser is declared to be a function that takes in some generic input type and returns
an optional tuple pairing the result with the remaining input to be parsed. As I've
blogged before, F#'s option type is kinda like C#'s Nullable type, so a parser that
returns None is considered to have failed to parse the input.
</p>
        <p>
Next up is are the monad functions Bind and Result. The only significant change from
the C# version is that I used the custom operator &gt;&gt;= for the Bind function.
So instead of calling "Item().Bind(some_function)", we can call "Item &gt;&gt;= some_function".
F# functions aren't attached to a type like C# extension methods are, so this is the
only way to get the more readable infix notation. I'm using &gt;&gt;= as the bind
operator because that's the operator <a href="http://www.haskell.org/haskellwiki/Monad">Haskell
uses</a> for their monad function. Other than the custom operator name, Bind and Result
work identically to their C# counterparts. Note, I explicitly specified the return
type of Bind, Result and Item, but I didn't have to. F# can infer the types of all
the parameters from usage just fine. I added the type specifications for the reader,
in case you're not familiar with F#'s syntax. 
</p>
        <p>
Likewise, Item is identical to the C# version including using strings as the parse
input, except for than the F# syntax. Typically, in a real parsing app you would use
an intrinsic list of chars instead of strings, since F#s list is a much more efficient
data structure than strings for operations that strip characters off the head of the
list (like parsers are wont to do). However, I wanted to make this code as similar
to the previous code, so I stuck with strings.
</p>
        <p>
Finally, we have BestTwoItems. Again, syntax aside, it's exactly like it's C# cousin
though I did use the slightly more compact sprintf function instead of string.Format.
Again, while BestTwoItems it works well, it uses the same nested anonymous function
syntax from the C# version. Maybe I shouldn't have called it "BestTwoItems"!
</p>
        <p>
However, in F# it's possible to define a custom syntax for your monad that let's you
write the function this way:
</p>
        <div style="font-family: consolas,lucida console,courier new">
          <span style="color: blue">let</span> VeryBestTwoItems
= 
<br>
    parse <span style="color: blue">{</span><br>
        <span style="color: blue">let</span>! v1
= Item 
<br>
        <span style="color: blue">let</span>! v2
= Item 
<br>
        <span style="color: blue">return</span> sprintf <span style="color: maroon">"%c%c"</span> v1
v2 <span style="color: blue">}</span></div>
        <p>
With this monadic syntax, we've now completely eliminated not only the Parser delegate
and the input string, but also the nested anonymous functions needed by the Bind function,
making the code appear completely sequential. 
</p>
        <p>
The secret to making this work is the parse monad object. It the code above, the word
parse almost feels like a language keyword, but it's not. It's actually an instance
of an parse monad object with a specific signature. F# knows how to take the syntax
above and combine it with the parse monad object to produce the right code. Here's
the parse monad:
</p>
        <div style="font-family: consolas,lucida console,courier new">
          <span style="color: blue">type</span> ParseMonad<span style="color: blue">(</span><span style="color: blue">)</span> = 
<br>
    <span style="color: blue">member</span> w<span style="color: blue">.</span>Delay<span style="color: blue">(</span>f<span style="color: blue">)</span> = <span style="color: blue">fun</span> input <span style="color: blue">-&gt;</span> f <span style="color: blue">(</span><span style="color: blue">)</span> input  
<br>
    <span style="color: blue">member</span> w<span style="color: blue">.</span>Return<span style="color: blue">(</span>v<span style="color: blue">)</span> =
Result v  
<br>
    <span style="color: blue">member</span> w<span style="color: blue">.</span>Bind<span style="color: blue">(</span>p,
f<span style="color: blue">)</span> = p &gt;&gt;= f 
<br>
     
<br><span style="color: blue">let</span> parse = ParseMonad<span style="color: blue">(</span><span style="color: blue">)</span></div>
        <p>
As you can see, there's an obvious direct correlation of Result and Bind functions
we defined last time and the Return and Bind methods in the ParseMonad. The only thing
we haven't seen before is the Delay method. Monads are one of of F#'s many <a href="http://research.microsoft.com/projects/fsharp/manual/spec2.aspx#_Toc202383770">delayed
expressions</a>. F# wraps the entire monad in a call to Delay to ensure the monad
isn't executed prematurely. 
</p>
        <p>
As per the <a href="http://research.microsoft.com/projects/fsharp/manual/spec2.aspx#_Toc202383771">F#
grammar spec</a>, there are several other functions you can define on your monad if
you so choose. My "real" parser monad also implements Zero and Combine. Zero returns
a parser that unconditionally fails. By defining Zero on my monad object, I can write
ifs without elses, the parser monad will implicitly inject Zero clause as your else
statement. Combine combines results (I know, a shocker!). I use it as a prioritized
choice. In other words, when you Combine two parsers, you only call the second parser
if calling the first parsers fails. Prioritized Choice is used very often in PEGs,
which is why I chose to define it this way.
</p>
        <p>
F# monadic syntax also support For, Let, While, Using, TryFinally and TryWith. Frankly,
I haven't spent much time thinking about scenarios where you'd use these other syntax
elements. The only one that's obvious to me is Using for deterministic finalization,
which you could see using anywhere you access IDispoasble objects. Here's hoping the
F# folks document in detail how to use this powerful syntax.
</p>
        <p>
So that's it for basic monads in F#. I've gotten some great comments (and one less
than great comments) as I've written this series. In my last post on monads (in this
series at least) I'll repost some of those comments as well as provide some concluding
thoughts. 
</p>
        <img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=9b8f0a29-ba33-46a2-a34d-ab470fa5e59a"></img>
      <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Devhawk?a=TyV0GK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=TyV0GK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=qTR3fK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=qTR3fK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=aY8hqK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=aY8hqK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=FGjLFK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=FGjLFK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=T6beVk"><img src="http://feeds.feedburner.com/~f/Devhawk?i=T6beVk" border="0"></img></a>
</div>]]></content:encoded><description>&lt;p&gt;
In the &lt;a href="http://devhawk.net/2008/08/01/Monadic+Philosophy+Part+3+The+Parser+Monad+In+C.aspx"&gt;last
post&lt;/a&gt;, I built out a basic parser monad in C#. While the approach worked OK, the
syntax is still a little foreign to your typical .NET programmer, what with it's nested
anonymous functions and all. Now, I'm going to translate that code to F# and take
a look at the special monadic syntax F# supports that makes using monads as easy any
sequential code.
&lt;/p&gt;
&lt;p&gt;
First, let's translate our Parser delegate, Bind, Result and Item functions over to
F#. Just for kicks, let's also port over the final version of TwoItems too.
&lt;/p&gt;
&lt;div style="font-family: consolas,lucida console,courier new"&gt;&lt;span style="color: blue"&gt;type&lt;/span&gt; Parser&amp;lt;'input,
'result&amp;gt; = 'input&lt;span style="color: blue"&gt;-&amp;gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue"&gt;(&lt;/span&gt;'result
* 'input&lt;span style="color: blue"&gt;)&lt;/span&gt; option 
&lt;br&gt;
&lt;br&gt;
&lt;span style="color: green"&gt;// the Bind function, defined as a custom operator&lt;/span&gt; 
&lt;br&gt;
&lt;span style="color: blue"&gt;let&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue"&gt;(&lt;/span&gt;&amp;gt;&amp;gt;=&lt;span style="color: blue"&gt;)&lt;/span&gt; p
f &lt;span style="color: blue"&gt;:&lt;/span&gt; Parser&amp;lt;'i,'r&amp;gt; =&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;fun&lt;/span&gt; input &lt;span style="color: blue"&gt;-&amp;gt;&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;match&lt;/span&gt; p
input &lt;span style="color: blue"&gt;with&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;|&lt;/span&gt; Some&lt;span style="color: blue"&gt;(&lt;/span&gt;value,
input&lt;span style="color: blue"&gt;)&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue"&gt;-&amp;gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue"&gt;(&lt;/span&gt;f
value&lt;span style="color: blue"&gt;)&lt;/span&gt; input 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;|&lt;/span&gt; None &lt;span style="color: blue"&gt;-&amp;gt;&lt;/span&gt; None 
&lt;br&gt;
&lt;br&gt;
&lt;span style="color: blue"&gt;let&lt;/span&gt; Result v &lt;span style="color: blue"&gt;:&lt;/span&gt; Parser&amp;lt;'i,'r&amp;gt;
= &lt;span style="color: blue"&gt;fun&lt;/span&gt; input &lt;span style="color: blue"&gt;-&amp;gt;&lt;/span&gt; Some&lt;span style="color: blue"&gt;(&lt;/span&gt;v,
input&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br&gt;
&lt;br&gt;
&lt;span style="color: blue"&gt;let&lt;/span&gt; Item &lt;span style="color: blue"&gt;:&lt;/span&gt; Parser&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: blue"&gt;char&lt;/span&gt;&amp;gt;
=&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;fun&lt;/span&gt; input &lt;span style="color: blue"&gt;-&amp;gt;&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue"&gt;string&lt;/span&gt;&lt;span style="color: blue"&gt;.&lt;/span&gt;IsNullOrEmpty&lt;span style="color: blue"&gt;(&lt;/span&gt;input&lt;span style="color: blue"&gt;)&lt;/span&gt;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;then&lt;/span&gt; None 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;else&lt;/span&gt; Some&lt;span style="color: blue"&gt;(&lt;/span&gt;input&lt;span style="color: blue"&gt;.&lt;/span&gt;&lt;span style="color: blue"&gt;[&lt;/span&gt;&lt;span style="color: maroon"&gt;0&lt;/span&gt;&lt;span style="color: blue"&gt;]&lt;/span&gt;,
input&lt;span style="color: blue"&gt;.&lt;/span&gt;Substring&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: maroon"&gt;1&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br&gt;
&lt;br&gt;
&lt;span style="color: blue"&gt;let&lt;/span&gt; BestTwoItems =&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Item &amp;gt;&amp;gt;= &lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;fun&lt;/span&gt; v1 &lt;span style="color: blue"&gt;-&amp;gt;&lt;/span&gt;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Item &amp;gt;&amp;gt;= &lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;fun&lt;/span&gt; v2 &lt;span style="color: blue"&gt;-&amp;gt;&lt;/span&gt;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Result &lt;span style="color: blue"&gt;(&lt;/span&gt;sprintf &lt;span style="color: maroon"&gt;"%c%c"&lt;/span&gt; v1
v2&lt;span style="color: blue"&gt;)&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;/div&gt;
&lt;p&gt;
First, we start with the declaration of the Parser type. Unlike C#, F# has built in
support for tuples, so I didn't bother to define a Result type (just the Result function).
A Parser is declared to be a function that takes in some generic input type and returns
an optional tuple pairing the result with the remaining input to be parsed. As I've
blogged before, F#'s option type is kinda like C#'s Nullable type, so a parser that
returns None is considered to have failed to parse the input.
&lt;/p&gt;
&lt;p&gt;
Next up is are the monad functions Bind and Result. The only significant change from
the C# version is that I used the custom operator &amp;gt;&amp;gt;= for the Bind function.
So instead of calling "Item().Bind(some_function)", we can call "Item &amp;gt;&amp;gt;= some_function".
F# functions aren't attached to a type like C# extension methods are, so this is the
only way to get the more readable infix notation. I'm using &amp;gt;&amp;gt;= as the bind
operator because that's the operator &lt;a href="http://www.haskell.org/haskellwiki/Monad"&gt;Haskell
uses&lt;/a&gt; for their monad function. Other than the custom operator name, Bind and Result
work identically to their C# counterparts. Note, I explicitly specified the return
type of Bind, Result and Item, but I didn't have to. F# can infer the types of all
the parameters from usage just fine. I added the type specifications for the reader,
in case you're not familiar with F#'s syntax. 
&lt;/p&gt;
&lt;p&gt;
Likewise, Item is identical to the C# version including using strings as the parse
input, except for than the F# syntax. Typically, in a real parsing app you would use
an intrinsic list of chars instead of strings, since F#s list is a much more efficient
data structure than strings for operations that strip characters off the head of the
list (like parsers are wont to do). However, I wanted to make this code as similar
to the previous code, so I stuck with strings.
&lt;/p&gt;
&lt;p&gt;
Finally, we have BestTwoItems. Again, syntax aside, it's exactly like it's C# cousin
though I did use the slightly more compact sprintf function instead of string.Format.
Again, while BestTwoItems it works well, it uses the same nested anonymous function
syntax from the C# version. Maybe I shouldn't have called it "BestTwoItems"!
&lt;/p&gt;
&lt;p&gt;
However, in F# it's possible to define a custom syntax for your monad that let's you
write the function this way:
&lt;/p&gt;
&lt;div style="font-family: consolas,lucida console,courier new"&gt;&lt;span style="color: blue"&gt;let&lt;/span&gt; VeryBestTwoItems
= 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; parse &lt;span style="color: blue"&gt;{&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;let&lt;/span&gt;! v1
= Item 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;let&lt;/span&gt;! v2
= Item 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; sprintf &lt;span style="color: maroon"&gt;"%c%c"&lt;/span&gt; v1
v2 &lt;span style="color: blue"&gt;}&lt;/span&gt;
&lt;/div&gt;
&lt;p&gt;
With this monadic syntax, we've now completely eliminated not only the Parser delegate
and the input string, but also the nested anonymous functions needed by the Bind function,
making the code appear completely sequential. 
&lt;/p&gt;
&lt;p&gt;
The secret to making this work is the parse monad object. It the code above, the word
parse almost feels like a language keyword, but it's not. It's actually an instance
of an parse monad object with a specific signature. F# knows how to take the syntax
above and combine it with the parse monad object to produce the right code. Here's
the parse monad:
&lt;/p&gt;
&lt;div style="font-family: consolas,lucida console,courier new"&gt;&lt;span style="color: blue"&gt;type&lt;/span&gt; ParseMonad&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt; = 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;member&lt;/span&gt; w&lt;span style="color: blue"&gt;.&lt;/span&gt;Delay&lt;span style="color: blue"&gt;(&lt;/span&gt;f&lt;span style="color: blue"&gt;)&lt;/span&gt; = &lt;span style="color: blue"&gt;fun&lt;/span&gt; input &lt;span style="color: blue"&gt;-&amp;gt;&lt;/span&gt; f &lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt; input&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;member&lt;/span&gt; w&lt;span style="color: blue"&gt;.&lt;/span&gt;Return&lt;span style="color: blue"&gt;(&lt;/span&gt;v&lt;span style="color: blue"&gt;)&lt;/span&gt; =
Result v&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;member&lt;/span&gt; w&lt;span style="color: blue"&gt;.&lt;/span&gt;Bind&lt;span style="color: blue"&gt;(&lt;/span&gt;p,
f&lt;span style="color: blue"&gt;)&lt;/span&gt; = p &amp;gt;&amp;gt;= f 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&lt;span style="color: blue"&gt;let&lt;/span&gt; parse = ParseMonad&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt;
&lt;/div&gt;
&lt;p&gt;
As you can see, there's an obvious direct correlation of Result and Bind functions
we defined last time and the Return and Bind methods in the ParseMonad. The only thing
we haven't seen before is the Delay method. Monads are one of of F#'s many &lt;a href="http://research.microsoft.com/projects/fsharp/manual/spec2.aspx#_Toc202383770"&gt;delayed
expressions&lt;/a&gt;. F# wraps the entire monad in a call to Delay to ensure the monad
isn't executed prematurely. 
&lt;/p&gt;
&lt;p&gt;
As per the &lt;a href="http://research.microsoft.com/projects/fsharp/manual/spec2.aspx#_Toc202383771"&gt;F#
grammar spec&lt;/a&gt;, there are several other functions you can define on your monad if
you so choose. My "real" parser monad also implements Zero and Combine. Zero returns
a parser that unconditionally fails. By defining Zero on my monad object, I can write
ifs without elses, the parser monad will implicitly inject Zero clause as your else
statement. Combine combines results (I know, a shocker!). I use it as a prioritized
choice. In other words, when you Combine two parsers, you only call the second parser
if calling the first parsers fails. Prioritized Choice is used very often in PEGs,
which is why I chose to define it this way.
&lt;/p&gt;
&lt;p&gt;
F# monadic syntax also support For, Let, While, Using, TryFinally and TryWith. Frankly,
I haven't spent much time thinking about scenarios where you'd use these other syntax
elements. The only one that's obvious to me is Using for deterministic finalization,
which you could see using anywhere you access IDispoasble objects. Here's hoping the
F# folks document in detail how to use this powerful syntax.
&lt;/p&gt;
&lt;p&gt;
So that's it for basic monads in F#. I've gotten some great comments (and one less
than great comments) as I've written this series. In my last post on monads (in this
series at least) I'll repost some of those comments as well as provide some concluding
thoughts. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=9b8f0a29-ba33-46a2-a34d-ab470fa5e59a" /&gt;</description><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://devhawk.net/Trackback.aspx?guid=9b8f0a29-ba33-46a2-a34d-ab470fa5e59a</trackback:ping><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/pingback.aspx</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/PermaLink,guid,9b8f0a29-ba33-46a2-a34d-ab470fa5e59a.aspx</pingback:target><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/CommentView,guid,9b8f0a29-ba33-46a2-a34d-ab470fa5e59a.aspx</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/SyndicationService.asmx/GetEntryCommentsRss?guid=9b8f0a29-ba33-46a2-a34d-ab470fa5e59a</wfw:commentRss><feedburner:origLink>http://devhawk.net/2008/08/01/Monadic+Philosophy+Part+4+The+Parser+Monad+In+F.aspx</feedburner:origLink></item><item><title>McCain's Dick Move of the Week</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/352967636/McCains+Dick+Move+Of+The+Week.aspx</link><category>Politics</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Harry Pierson</dc:creator><pubDate>Fri, 01 Aug 2008 15:39:16 -0500</pubDate><guid isPermaLink="false">http://devhawk.net/PermaLink,guid,be8c3c37-012b-499f-a1d2-1db86c5771b5.aspx</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
        <p>
          <a href="http://www.thedailyshow.com/video/index.jhtml?videoId=178207&amp;title=dick-move-of-the-week-mccain">This
segment</a> on last night's Daily Show was fantastic. 
</p>
        <p>
          <embed name="comedy_central_player" pluginspage="http://www.macromedia.com/go/getflashplayer" align="middle" src="http://www.thedailyshow.com/sitewide/video_player/view/default/swf.jhtml" width="332" height="316" type="application/x-shockwave-flash" allownetworking="external" allowscriptaccess="always" bgcolor="#cccccc" quality="high" flashvars="videoId=178207">
          </embed>
        </p>
        <p>
At the rate McCain's going, Jon Stewart is going to have to change this segment to
"McCain's Dick Move of the Day". I don't know which is more embarrassing, McCain's
campaign or the mainstream media coverage of the campaign. 
</p>
        <img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=be8c3c37-012b-499f-a1d2-1db86c5771b5"></img>
      <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Devhawk?a=uWN7wK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=uWN7wK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=wakPvK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=wakPvK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=9H6ESK"><img src="http://feeds.feedburner.com/~f/Devhawk?i=9H6ESK" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=TbV50K"><img src="http://feeds.feedburner.com/~f/Devhawk?i=TbV50K" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=XJorQk"><img src="http://feeds.feedburner.com/~f/Devhawk?i=XJorQk" border="0"></img></a>
</div>]]></content:encoded><description>&lt;p&gt;
&lt;a href="http://www.thedailyshow.com/video/index.jhtml?videoId=178207&amp;amp;title=dick-move-of-the-week-mccain"&gt;This
segment&lt;/a&gt; on last night's Daily Show was fantastic. 
&lt;/p&gt;
&lt;p&gt;
&lt;embed name="comedy_central_player" pluginspage="http://www.macromedia.com/go/getflashplayer" align="middle" src="http://www.thedailyshow.com/sitewide/video_player/view/default/swf.jhtml" width="332" height="316" type="application/x-shockwave-flash" allownetworking="external" allowscriptaccess="always" bgcolor="#cccccc" quality="high" flashvars="videoId=178207"&gt;
&lt;/p&gt;
&lt;p&gt;
At the rate McCain's going, Jon Stewart is going to have to change this segment to
"McCain's Dick Move of the Day". I don't know which is more embarrassing, McCain's
campaign or the mainstream media coverage of the campaign. 
&lt;/p&gt;
&gt;&lt;img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=be8c3c37-012b-499f-a1d2-1db86c5771b5" /&gt;</description><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://devhawk.net/Trackback.aspx?guid=be8c3c37-012b-499f-a1d2-1db86c5771b5</trackback:ping><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/pingback.aspx</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/PermaLink,guid,be8c3c37-012b-499f-a1d2-1db86c5771b5.aspx</pingback:target><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/CommentView,guid,be8c3c37-012b-499f-a1d2-1db86c5771b5.aspx</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/SyndicationService.asmx/GetEntryCommentsRss?guid=be8c3c37-012b-499f-a1d2-1db86c5771b5</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">4</slash:comments><feedburner:origLink>http://devhawk.net/2008/08/01/McCains+Dick+Move+Of+The+Week.aspx</feedburner:origLink></item><item><title>Monadic Philosophy Part 3 - The Parser Monad in C#</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/352223384/Monadic+Philosophy+Part+3+The+Parser+Monad+In+C.aspx</link><category>C#</category><category>F#</category><category>Functional Programming</category><category>Monads</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Harry Pierson</dc:creator><pubDate>Thu, 31 Jul 2008 22:47:30 -0500</pubDate><guid isPermaLink="false">http://devhawk.net/PermaLink,guid,f0fb5461-eb30-4268-a4b3-7262276768cb.aspx</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
        <p>
(If you disregarded <a href="http://devhawk.net/2008/07/30/Pushed+The+Wrong+Button.aspx">my
advice</a> and read the previous version of this post, please note I rewrote this
post significantly so you'll probably want to read it again.)
</p>
        <p>
In the <a href="http://devhawk.net/2008/07/30/Monadic+Philosophy+Part+2+The+LINQ+Monad.aspx">last
post</a>, we looked at how LINQ is a monad and how IEnumerable is a pseudo-functional
construct. However, C#'s intrinsic collection support - aka foreach and yield return
- really obscure how you might go about building your own monad. So for this post,
we're going to take a look at a parsing monad instead. Just as LINQ broke the big
problem of queries into a collection of standard query operators that were composable,
we want to take the same approach for parsers. 
</p>
        <p>
Note, I'm going to stick with C# for now, and get into F# monads in my next post.
Quick shout out to <a href="http://blogs.msdn.com/lukeh/archive/2007/08/19/monadic-parser-combinators-using-c-3-0.aspx">Luke
Hoban</a> and <a href="http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!124.entry">Brian
McNamara</a>, from whom I <strike>stole</strike> obtained some of the code below.
</p>
        <p>
Quick refresher: I've described a monad as a sequence of computations with a context
flow. Since C# has explicit sequencing, we want to focus on the context flow. For
LINQ, the context was IEnumerable. For parsers, we could define an similar IParser
interface like this:
</p>
        <div style="font-family: consolas,lucida console,courier new">
          <span style="color: blue">class</span> Tuple&lt;T1,
T2&gt; 
<br>
{ 
<br>
    <span style="color: blue">public</span> <span style="color: blue">readonly</span> T1
Item1; 
<br>
    <span style="color: blue">public</span> <span style="color: blue">readonly</span> T2
Item2; 
<br>
    <span style="color: blue">public</span> Tuple(T1 val1, T2 val2)
{ Item1 = val1; Item2 = val2; } 
<br>
} 
<br><br><span style="color: blue">class</span> Result&lt;T&gt; : Tuple&lt;T, <span style="color: blue">string</span>&gt; 
<br>
{ 
<br>
    <span style="color: blue">public</span> Result(T val, <span style="color: blue">string</span> rest)
: <span style="color: blue">base</span>(val, rest) { } 
<br>
} 
<br><br><span style="color: blue">interface</span> IParser&lt;T&gt; 
<br>
{ 
<br>
    Result&lt;T&gt; Parse(<span style="color: blue">string</span> input); 
<br>
}
</div>
        <p>
The Parse function takes a string to be parsed as input and returns the parsing result
which pairs the semantic value with with the remaining string input to be parsed.
I've built out a simple generic tuple class because I know I'll use it again later.
I've <a href="http://devhawk.net/2006/08/22/Language+Features+I+Wish+C+Had+Tuples.aspx">long
wished</a> C# would support intrinsic tuples like F# does. For convenience, I've also
created a strongly typed subclass of Tuple to represent parse results where the second
item is a string, to save some typing. Since Result is a class, it can be null which
means the the Parser failed to parse the input. 
</p>
        <p>
The problem with this approach is that unlike IEnumerable, the C# compiler has no
built-in knowledge of this interface. That means there are no easy-to-use keywords
like foreach and yield return that can do our heavy lifting of consuming or creating
these IParser types for us. Instead, we would have to explicitly declare classes to
implement the interface. As we add more and more parsers, that additional overhead
of creating types would become more and more unwieldy. Instead, let's redefine Parser
as a delegate.
</p>
        <div style="font-family: consolas,lucida console,courier new">
          <span style="color: blue">delegate</span> Result&lt;T&gt;
Parser&lt;T&gt;(<span style="color: blue">string</span> input);
</div>
        <p>
The benefit of this approach is that you can create Parser delegates inside functions,
using C#'s anonymous delegate syntax, without the overhead of creating a type. For
example, here's a function to create a simple primitive parser that strips the first
character off the parse string and returns it as the parse result:
</p>
        <div style="font-family: consolas,lucida console,courier new">
          <span style="color: blue">static</span> Parser&lt;<span style="color: blue">char</span>&gt;
Item() 
<br>
{ 
<br>
    <span style="color: blue">return</span> input =&gt; 
<br>
        { 
<br>
            <span style="color: blue">return</span> <span style="color: blue">string</span>.IsNullOrEmpty(input) 
<br>
               
? <span style="color: blue">null</span><br>
               
: <span style="color: blue">new</span> Result&lt;<span style="color: blue">char</span>&gt;(input[<span style="color: maroon">0</span>],
input.Substring(<span style="color: maroon">1</span>)); 
<br>
        }; 
<br>
}
</div>
        <p>
That's a lot more convenient than building a type just to implement a single method. 
</p>
        <p>
Now that we have our Parser type, we need to think about how to compose Parsers so
that we can flow context between them. Much as LINQ provides a collection of primitive
query operators (Select, Where, OrderBy, etc), you would expect a monadic parser library
to provide a collection of primitive parsers (Item, Satisfy, AnyOf, ItemEqual, etc),
that you could combine into higher-order parsers along with some language specific
lower-order parsers. Here's an example from the the <a href="http://pdos.csail.mit.edu/~baford/packrat/popl04/peg-popl04.pdf">PEG
grammar</a>:
</p>
        <p>
    Primary &lt;- Identifier !LEFTARROW / OPEN Expression CLOSE / Literal
/ Class / DOT
</p>
        <p>
The Primary parser depends on some high-order language specific parsers (Identifier,
Expression, Literal and Class) as well as some language specific low-order tokenizer
style parsers (LEFTARROW, OPEN, CLOSE and DOT) and finally some language-independent
primitive parsers (the failure predicate ! and the prioritized choice operator /). 
</p>
        <p>
So how should we compose these various Parsers? LINQ query operators were fairly easy
to compose because they all take in and return the same type (IEnumerable) so you
can simply chain them together. Parsers are a little trickier because the inputs and
outputs are asymmetric - i.e. they take a string, but return a Result - so simple
chaining won't work. 
</p>
        <p>
We could combine the parsers sequentially, taking the parse string returned from first
parser and feed it into the second. Then we could combine the two parse values in
a Tuple to return them (you see why I created a generic Tuple class?) resulting in
a function that looks like this:
</p>
        <div style="font-family: consolas,lucida console,courier new">
          <span style="color: blue">static</span> Parser&lt;Tuple&lt;T1,T2&gt;&gt;
Join&lt;T1,T2&gt;(<span style="color: blue">this</span> Parser&lt;T1&gt; p1, Parser&lt;T2&gt;
p2)  
<br>
{  
<br>
    <span style="color: blue">return</span> input =&gt;  
<br>
        {  
<br>
            <span style="color: blue">var</span> ret1
= p1(input);  
<br>
            <span style="color: blue">if</span> (ret1
== <span style="color: blue">null</span>)  
<br>
                <span style="color: blue">return</span> <span style="color: blue">null</span>;  
<br><br>
            <span style="color: blue">var</span> ret2
= p2(ret1.Item2);  
<br>
            <span style="color: blue">if</span> (ret2
== <span style="color: blue">null</span>)  
<br>
                <span style="color: blue">return</span> <span style="color: blue">null</span>;  
<br><br>
            <span style="color: blue">return</span> <span style="color: blue">new</span> Result&lt;Tuple&lt;T1,T2&gt;&gt;(  
<br>
                <span style="color: blue">new</span> Tuple&lt;T1,
T2&gt;(ret1.Item1, ret2.Item1),  
<br>
               
ret2.Item2);  
<br>
        };  
<br>
}
</div>
        <p>
Note this is an extension method so we can call Parser1.Join(Parser2) rather than
the less fluent Join(Parser1, Parser2). I was going to call this function Combine,
but there's already a static Combine method on the Delegate type that caused a conflict,
so I used Join instead. 
</p>
        <p>
The Join approach works, but it's a bit unwieldy to return the parsing values in a
tuple. Every set of joined parsers will result in another level of tuple nesting in
the Result that's returned. That gets pretty ugly pretty fast. For example, lets say
we want to create a parser that combines two instances of Item. It looks like this:
</p>
        <div style="font-family: consolas,lucida console,courier new">
          <span style="color: blue">static</span> Parser&lt;Tuple&lt;<span style="color: blue">char</span>, <span style="color: blue">char</span>&gt;&gt;
TwoItems() 
<br>
{ 
<br>
    <span style="color: blue">return</span> Item().Plus(Item()); 
<br>
} 
<br></div>
        <p>
That's not so bad. But now look what happens if we combine the TwoItems parser with
another instance of Item:
</p>
        <div style="font-family: consolas,lucida console,courier new">
          <span style="color: blue">static</span> Parser&lt;Tuple&lt;Tuple&lt;<span style="color: blue">char</span>, <span style="color: blue">char</span>&gt;, <span style="color: blue">char</span>&gt;&gt;
ThreeItems() 
<br>
{ 
<br>
    <span style="color: blue">return</span> TwoItems().Plus(Item()); 
<br>
}
</div>
        <p>
The result is a nested tuple. Yuck. We need a better way. Enter the monadic bind.
The code looks like this:
</p>
        <div style="font-family: consolas,lucida console,courier new">
          <span style="color: blue">static</span> Parser&lt;U&gt;
Bind&lt;T, U&gt;(<span style="color: blue">this</span> Parser&lt;T&gt; p1, Func&lt;T,
Parser&lt;U&gt;&gt; fun) 
<br>
{ 
<br>
    <span style="color: blue">return</span> input =&gt; 
<br>
        { 
<br>
            <span style="color: blue">var</span> ret1
= p1(input); 
<br>
            <span style="color: blue">if</span> (ret1
== <span style="color: blue">null</span>) 
<br>
                <span style="color: blue">return</span> <span style="color: blue">null</span>; 
<br><br>
            <span style="color: blue">var</span> p2
= fun(ret1.Item1); 
<br>
            <span style="color: blue">if</span> (p2
== <span style="color: blue">null</span>) 
<br>
                <span style="color: blue">return</span> <span style="color: blue">null</span>; 
<br><br>
            <span style="color: blue">return</span> p2(ret1.Item2); 
<br>
        }; 
<br>
}
</div>
        <p>
Like the Join function above, Bind starts by calling the first parser function, returning
null if the parse fails. However, instead of calling to the second parser directly,
it calls to the provided function that generates the second parser. This function
acts as a <a href="http://en.wikipedia.org/wiki/Closure_%28computer_science%29">closure</a>,
packaging up the parse value from the first parser for later processing. Finally,
Bind calls to the generated second parser, feeding in the remaining text from the
first parser result. 
</p>
        <p>
This approach allows you to inject code that combines the parsing values however we
like rather than always pairing them up in a tuple. Here's a version of TwoItems that
binds a call to Item with a custom function that calls Item again and returns the
two characters as a string rather than a tuple:
</p>
        <div style="font-family: consolas,lucida console,courier new">
          <span style="color: blue">static</span> Parser&lt;<span style="color: blue">string</span>&gt;
BetterTwoItems() 
<br>
{ 
<br>
    <span style="color: blue">return</span> Item().Bind&lt;<span style="color: blue">char</span>, <span style="color: blue">string</span>&gt;( 
<br>
        val =&gt;  
<br>
        { 
<br>
            <span style="color: blue">return</span> input
=&gt; 
<br>
            { 
<br>
                <span style="color: blue">var</span> result
= Item()(input); 
<br>
                <span style="color: blue">return</span> <span style="color: blue">new</span> Result&lt;<span style="color: blue">string</span>&gt;( 
<br>
                    <span style="color: blue">string</span>.Format(<span style="color: maroon">"{0}{1}"</span>,
val, result.Item1), 
<br>
                   
result.Item2); 
<br>
            }; 
<br>
        }); 
<br>
}
</div>
        <p>
It's kinda strange to see a lambda expression that returns a lambda expression in
C#, but that's what this code does. The first lambda expression (val =&gt;) defines
the custom function, the second lambda expression (input =&gt;) defines the Parser
delegate. Val is the parse value from calling Item() the first time - ret1.Item1 in
the Bind function above. Input is the remainder of the parse string - ret1.Item2 from
the Bind function. 
</p>
        <p>
Unfortunately, while this approach avoids nested tuples for parse values, we've had
to give up quite a bit of simplicity. The original TwoItems method was a single line
of code. BetterTwoItems is significantly more complex. Furthermore, the double lambda
expression syntax confuses C#'s type inference, forcing you to explicitly specify
the generic types on the Bind method. Luckily there's a better way to write this.
However, let's start by rewriting the function like this:
</p>
        <div style="font-family: consolas,lucida console,courier new">
          <span style="color: blue">static</span> Parser&lt;<span style="color: blue">string</span>&gt;
SlightlyBetterTwoItems() 
<br>
{ 
<br>
    <span style="color: blue">return</span> Item().Bind( 
<br>
        v1 =&gt; Item().Bind&lt;<span style="color: blue">char</span>, <span style="color: blue">string</span>&gt;( 
<br>
            v2 =&gt; 
<br>
            { 
<br>
                <span style="color: blue">return</span> input
=&gt; 
<br>
               
{ 
<br>
                    <span style="color: blue">return</span> <span style="color: blue">new</span> Result&lt;<span style="color: blue">string</span>&gt;( 
<br>
                        <span style="color: blue">string</span>.Format(<span style="color: maroon">"{0}{1}"</span>,
v1, v2), 
<br>
                       
input); 
<br>
               
}; 
<br>
            })); 
<br>
}
</div>
        <p>
SlightlyBetterTwoItems pulls the second call to Item out into a second Bind operation.
The point of this refactoring is to make it clear that we can view this function as
a call to Item, bound to a second call to Item, bound to custom function to return
a Parser that returns the two parse value chars formatted as a string. You'll notice
that by eliminating the the double lambda expression on the first call to Bind, we
were able to drop out the explicit generic type specification. 
</p>
        <p>
This version is a little clearer, but we can make it clearer yet. It turns out that
wrapping up a parse value in a Parser that unconditionally returns the parse value
and the parse text input in a Result is a very common operation. So let's create a
primitive function Result to wrap up a parse value in a Parser delegate and build
our final version of TwoItems that uses it.
</p>
        <div style="font-family: consolas,lucida console,courier new">
          <span style="color: blue">static</span> Parser&lt;T&gt;
Result&lt;T&gt;(T val)  
<br>
{  
<br>
    <span style="color: blue">return</span> input =&gt; <span style="color: blue">new</span> Result&lt;T&gt;(val,
input);  
<br>
}  
<br><br><span style="color: blue">static</span> Parser&lt;<span style="color: blue">string</span>&gt;
BestTwoItems() 
<br>
{ 
<br>
    <span style="color: blue">return</span> Item().Bind( 
<br>
        v1 =&gt; Item().Bind( 
<br>
        v2 =&gt; Result(<span style="color: blue">string</span>.Format(<span style="color: maroon">"{0}{1}"</span>,
v1, v2)))); 
<br>
} 
</div>
        <p>
Now it's very clear that we have a call to Item, bound to a second call to item, which
is in turn bound to a call to Result. We've now dropped all use of double lambdas,
which means C# can infer the types to each of our Bind calls implicitly. But more
importantly, do you see <em>any</em> reference to Parser&lt;T&gt; delegates or input
strings in this code? Only in the return type specification. Just as LINQ hides the
specifics of flowing IEnumerable or enumerator objects between standard query operators,
the parser monad hides the specifics of flowing Parser delegates or input strings
between parse operations. 
</p>
        <p>
The Parser delegate plus the Bind and Result methods are all there are to our basic
parser monad. Seriously, all that worry that monad "is a bit obscure and sounds a
little daunting" and it's really just two functions and a delegate type. 
</p>
        <p>
While this code is fairly straight forward, the whole nested lambdas expressions is
fairly atypical syntax that some developers might have a hard time understanding.
Unfortunately, if we're writing our parsers in C#, we're kinda stuck with this syntax.
However, F# has a special syntax that lets you write what looks like normal sequential
code, while still flowing the Parser context between parse operations exactly like
the code above does. We'll take a look at that syntax in the next post.
</p>
        <img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=f0fb5461-eb30-4268-a4b3-7262276768cb"></img>
      <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Devhawk?a=7ttXjJ"><img src="http://feeds.feedburner.com/~f/Devhawk?i=7ttXjJ" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=NGIOIJ"><img src="http://feeds.feedburner.com/~f/Devhawk?i=NGIOIJ" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=nXbxjJ"><img src="http://feeds.feedburner.com/~f/Devhawk?i=nXbxjJ" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=qOmVnJ"><img src="http://feeds.feedburner.com/~f/Devhawk?i=qOmVnJ" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=rWZEZj"><img src="http://feeds.feedburner.com/~f/Devhawk?i=rWZEZj" border="0"></img></a>
</div>]]></content:encoded><description>&lt;p&gt;
(If you disregarded &lt;a href="http://devhawk.net/2008/07/30/Pushed+The+Wrong+Button.aspx"&gt;my
advice&lt;/a&gt; and read the previous version of this post, please note I rewrote this
post significantly so you'll probably want to read it again.)
&lt;/p&gt;
&lt;p&gt;
In the &lt;a href="http://devhawk.net/2008/07/30/Monadic+Philosophy+Part+2+The+LINQ+Monad.aspx"&gt;last
post&lt;/a&gt;, we looked at how LINQ is a monad and how IEnumerable is a pseudo-functional
construct. However, C#'s intrinsic collection support - aka foreach and yield return
- really obscure how you might go about building your own monad. So for this post,
we're going to take a look at a parsing monad instead. Just as LINQ broke the big
problem of queries into a collection of standard query operators that were composable,
we want to take the same approach for parsers. 
&lt;/p&gt;
&lt;p&gt;
Note, I'm going to stick with C# for now, and get into F# monads in my next post.
Quick shout out to &lt;a href="http://blogs.msdn.com/lukeh/archive/2007/08/19/monadic-parser-combinators-using-c-3-0.aspx"&gt;Luke
Hoban&lt;/a&gt; and &lt;a href="http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!124.entry"&gt;Brian
McNamara&lt;/a&gt;, from whom I &lt;strike&gt;stole&lt;/strike&gt; obtained some of the code below.
&lt;/p&gt;
&lt;p&gt;
Quick refresher: I've described a monad as a sequence of computations with a context
flow. Since C# has explicit sequencing, we want to focus on the context flow. For
LINQ, the context was IEnumerable. For parsers, we could define an similar IParser
interface like this:
&lt;/p&gt;
&lt;div style="font-family: consolas,lucida console,courier new"&gt;&lt;span style="color: blue"&gt;class&lt;/span&gt; Tuple&amp;lt;T1,
T2&amp;gt; 
&lt;br&gt;
{ 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue"&gt;readonly&lt;/span&gt; T1
Item1; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue"&gt;readonly&lt;/span&gt; T2
Item2; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; Tuple(T1 val1, T2 val2)
{ Item1 = val1; Item2 = val2; } 
&lt;br&gt;
} 
&lt;br&gt;
&lt;br&gt;
&lt;span style="color: blue"&gt;class&lt;/span&gt; Result&amp;lt;T&amp;gt; : Tuple&amp;lt;T, &lt;span style="color: blue"&gt;string&lt;/span&gt;&amp;gt; 
&lt;br&gt;
{ 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;public&lt;/span&gt; Result(T val, &lt;span style="color: blue"&gt;string&lt;/span&gt; rest)
: &lt;span style="color: blue"&gt;base&lt;/span&gt;(val, rest) { } 
&lt;br&gt;
} 
&lt;br&gt;
&lt;br&gt;
&lt;span style="color: blue"&gt;interface&lt;/span&gt; IParser&amp;lt;T&amp;gt; 
&lt;br&gt;
{ 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Result&amp;lt;T&amp;gt; Parse(&lt;span style="color: blue"&gt;string&lt;/span&gt; input); 
&lt;br&gt;
}
&lt;/div&gt;
&lt;p&gt;
The Parse function takes a string to be parsed as input and returns the parsing result
which pairs the semantic value with with the remaining string input to be parsed.
I've built out a simple generic tuple class because I know I'll use it again later.
I've &lt;a href="http://devhawk.net/2006/08/22/Language+Features+I+Wish+C+Had+Tuples.aspx"&gt;long
wished&lt;/a&gt; C# would support intrinsic tuples like F# does. For convenience, I've also
created a strongly typed subclass of Tuple to represent parse results where the second
item is a string, to save some typing. Since Result is a class, it can be null which
means the the Parser failed to parse the input. 
&lt;/p&gt;
&lt;p&gt;
The problem with this approach is that unlike IEnumerable, the C# compiler has no
built-in knowledge of this interface. That means there are no easy-to-use keywords
like foreach and yield return that can do our heavy lifting of consuming or creating
these IParser types for us. Instead, we would have to explicitly declare classes to
implement the interface. As we add more and more parsers, that additional overhead
of creating types would become more and more unwieldy. Instead, let's redefine Parser
as a delegate.
&lt;/p&gt;
&lt;div style="font-family: consolas,lucida console,courier new"&gt;&lt;span style="color: blue"&gt;delegate&lt;/span&gt; Result&amp;lt;T&amp;gt;
Parser&amp;lt;T&amp;gt;(&lt;span style="color: blue"&gt;string&lt;/span&gt; input);
&lt;/div&gt;
&lt;p&gt;
The benefit of this approach is that you can create Parser delegates inside functions,
using C#'s anonymous delegate syntax, without the overhead of creating a type. For
example, here's a function to create a simple primitive parser that strips the first
character off the parse string and returns it as the parse result:
&lt;/p&gt;
&lt;div style="font-family: consolas,lucida console,courier new"&gt;&lt;span style="color: blue"&gt;static&lt;/span&gt; Parser&amp;lt;&lt;span style="color: blue"&gt;char&lt;/span&gt;&amp;gt;
Item() 
&lt;br&gt;
{ 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; input =&amp;gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(input) 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
? &lt;span style="color: blue"&gt;null&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
: &lt;span style="color: blue"&gt;new&lt;/span&gt; Result&amp;lt;&lt;span style="color: blue"&gt;char&lt;/span&gt;&amp;gt;(input[&lt;span style="color: maroon"&gt;0&lt;/span&gt;],
input.Substring(&lt;span style="color: maroon"&gt;1&lt;/span&gt;)); 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }; 
&lt;br&gt;
}
&lt;/div&gt;
&lt;p&gt;
That's a lot more convenient than building a type just to implement a single method. 
&lt;/p&gt;
&lt;p&gt;
Now that we have our Parser type, we need to think about how to compose Parsers so
that we can flow context between them. Much as LINQ provides a collection of primitive
query operators (Select, Where, OrderBy, etc), you would expect a monadic parser library
to provide a collection of primitive parsers (Item, Satisfy, AnyOf, ItemEqual, etc),
that you could combine into higher-order parsers along with some language specific
lower-order parsers. Here's an example from the the &lt;a href="http://pdos.csail.mit.edu/~baford/packrat/popl04/peg-popl04.pdf"&gt;PEG
grammar&lt;/a&gt;:
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Primary &amp;lt;- Identifier !LEFTARROW / OPEN Expression CLOSE / Literal
/ Class / DOT
&lt;/p&gt;
&lt;p&gt;
The Primary parser depends on some high-order language specific parsers (Identifier,
Expression, Literal and Class) as well as some language specific low-order tokenizer
style parsers (LEFTARROW, OPEN, CLOSE and DOT) and finally some language-independent
primitive parsers (the failure predicate ! and the prioritized choice operator /). 
&lt;/p&gt;
&lt;p&gt;
So how should we compose these various Parsers? LINQ query operators were fairly easy
to compose because they all take in and return the same type (IEnumerable) so you
can simply chain them together. Parsers are a little trickier because the inputs and
outputs are asymmetric - i.e. they take a string, but return a Result - so simple
chaining won't work. 
&lt;/p&gt;
&lt;p&gt;
We could combine the parsers sequentially, taking the parse string returned from first
parser and feed it into the second. Then we could combine the two parse values in
a Tuple to return them (you see why I created a generic Tuple class?) resulting in
a function that looks like this:
&lt;/p&gt;
&lt;div style="font-family: consolas,lucida console,courier new"&gt;&lt;span style="color: blue"&gt;static&lt;/span&gt; Parser&amp;lt;Tuple&amp;lt;T1,T2&amp;gt;&amp;gt;
Join&amp;lt;T1,T2&amp;gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt; Parser&amp;lt;T1&amp;gt; p1, Parser&amp;lt;T2&amp;gt;
p2)&amp;nbsp; 
&lt;br&gt;
{&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; input =&amp;gt;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;var&lt;/span&gt; ret1
= p1(input);&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (ret1
== &lt;span style="color: blue"&gt;null&lt;/span&gt;)&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue"&gt;null&lt;/span&gt;;&amp;nbsp; 
&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;var&lt;/span&gt; ret2
= p2(ret1.Item2);&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (ret2
== &lt;span style="color: blue"&gt;null&lt;/span&gt;)&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue"&gt;null&lt;/span&gt;;&amp;nbsp; 
&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue"&gt;new&lt;/span&gt; Result&amp;lt;Tuple&amp;lt;T1,T2&amp;gt;&amp;gt;(&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;new&lt;/span&gt; Tuple&amp;lt;T1,
T2&amp;gt;(ret1.Item1, ret2.Item1),&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
ret2.Item2);&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&amp;nbsp; 
&lt;br&gt;
}
&lt;/div&gt;
&lt;p&gt;
Note this is an extension method so we can call Parser1.Join(Parser2) rather than
the less fluent Join(Parser1, Parser2). I was going to call this function Combine,
but there's already a static Combine method on the Delegate type that caused a conflict,
so I used Join instead. 
&lt;/p&gt;
&lt;p&gt;
The Join approach works, but it's a bit unwieldy to return the parsing values in a
tuple. Every set of joined parsers will result in another level of tuple nesting in
the Result that's returned. That gets pretty ugly pretty fast. For example, lets say
we want to create a parser that combines two instances of Item. It looks like this:
&lt;/p&gt;
&lt;div style="font-family: consolas,lucida console,courier new"&gt;&lt;span style="color: blue"&gt;static&lt;/span&gt; Parser&amp;lt;Tuple&amp;lt;&lt;span style="color: blue"&gt;char&lt;/span&gt;, &lt;span style="color: blue"&gt;char&lt;/span&gt;&amp;gt;&amp;gt;
TwoItems() 
&lt;br&gt;
{ 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; Item().Plus(Item()); 
&lt;br&gt;
} 
&lt;br&gt;
&lt;/div&gt;
&lt;p&gt;
That's not so bad. But now look what happens if we combine the TwoItems parser with
another instance of Item:
&lt;/p&gt;
&lt;div style="font-family: consolas,lucida console,courier new"&gt;&lt;span style="color: blue"&gt;static&lt;/span&gt; Parser&amp;lt;Tuple&amp;lt;Tuple&amp;lt;&lt;span style="color: blue"&gt;char&lt;/span&gt;, &lt;span style="color: blue"&gt;char&lt;/span&gt;&amp;gt;, &lt;span style="color: blue"&gt;char&lt;/span&gt;&amp;gt;&amp;gt;
ThreeItems() 
&lt;br&gt;
{ 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; TwoItems().Plus(Item()); 
&lt;br&gt;
}
&lt;/div&gt;
&lt;p&gt;
The result is a nested tuple. Yuck. We need a better way. Enter the monadic bind.
The code looks like this:
&lt;/p&gt;
&lt;div style="font-family: consolas,lucida console,courier new"&gt;&lt;span style="color: blue"&gt;static&lt;/span&gt; Parser&amp;lt;U&amp;gt;
Bind&amp;lt;T, U&amp;gt;(&lt;span style="color: blue"&gt;this&lt;/span&gt; Parser&amp;lt;T&amp;gt; p1, Func&amp;lt;T,
Parser&amp;lt;U&amp;gt;&amp;gt; fun) 
&lt;br&gt;
{ 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; input =&amp;gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;var&lt;/span&gt; ret1
= p1(input); 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (ret1
== &lt;span style="color: blue"&gt;null&lt;/span&gt;) 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue"&gt;null&lt;/span&gt;; 
&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;var&lt;/span&gt; p2
= fun(ret1.Item1); 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;if&lt;/span&gt; (p2
== &lt;span style="color: blue"&gt;null&lt;/span&gt;) 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue"&gt;null&lt;/span&gt;; 
&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; p2(ret1.Item2); 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }; 
&lt;br&gt;
}
&lt;/div&gt;
&lt;p&gt;
Like the Join function above, Bind starts by calling the first parser function, returning
null if the parse fails. However, instead of calling to the second parser directly,
it calls to the provided function that generates the second parser. This funct