<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss version="2.0">
  <channel>
    <title>Planet F#</title>
    <description>Planet F#</description>
    <link>http://babelnova.net/planet</link>
    <docs>http://backend.userland.com/rss</docs>
    <generator>RSS.NET: http://www.rssdotnet.com/</generator>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/planet_fsharp" type="application/rss+xml" /><item>
      <title>The adventures of a Pythonista in Schemeland</title>
      <description>&lt;a rel="nofollow" target="_blank" href="http://www.artima.com/weblogs/viewpost.jsp?thread=238789"&gt;http://www.artima.com/weblogs/viewpost.jsp?thread=238789&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10811141-7640537307129078577?l=artyprog.blogspot.com'/&gt;&lt;/div&gt;&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247315400"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247315400" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/aQwYZx9YH7aa3KgnjTCCZik4oVg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aQwYZx9YH7aa3KgnjTCCZik4oVg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/aQwYZx9YH7aa3KgnjTCCZik4oVg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aQwYZx9YH7aa3KgnjTCCZik4oVg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=UgBfG86_ZTc:YTmMfuPb63M:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=UgBfG86_ZTc:YTmMfuPb63M:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=UgBfG86_ZTc:YTmMfuPb63M:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=UgBfG86_ZTc:YTmMfuPb63M:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=UgBfG86_ZTc:YTmMfuPb63M:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=UgBfG86_ZTc:YTmMfuPb63M:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=UgBfG86_ZTc:YTmMfuPb63M:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/UgBfG86_ZTc" height="1" width="1"/&gt;</description>
      <link>http://artyprog.blogspot.com/2009/07/adventures-of-pythonista-in-schemeland.html</link>
      <author>Salvatore</author>
      <pubDate>Sat, 11 Jul 2009 01:30:00 GMT</pubDate>
    </item>
    <item>
      <title>Beginning F#: Card Tricks</title>
      <description>&lt;a rel="nofollow" target="_blank" href="http://www.devx.com/dotnet/Article/40537/1954"&gt;http://www.devx.com/dotnet/Article/40537/1954&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10811141-2298916214308751211?l=artyprog.blogspot.com'/&gt;&lt;/div&gt;&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247311260"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247311260" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/64Ol4PFsyEwpWodUCuV3DYGrgTs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/64Ol4PFsyEwpWodUCuV3DYGrgTs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/64Ol4PFsyEwpWodUCuV3DYGrgTs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/64Ol4PFsyEwpWodUCuV3DYGrgTs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=NgkyQYf7VFU:UoOk8OcNMrU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=NgkyQYf7VFU:UoOk8OcNMrU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=NgkyQYf7VFU:UoOk8OcNMrU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=NgkyQYf7VFU:UoOk8OcNMrU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=NgkyQYf7VFU:UoOk8OcNMrU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=NgkyQYf7VFU:UoOk8OcNMrU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=NgkyQYf7VFU:UoOk8OcNMrU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/NgkyQYf7VFU" height="1" width="1"/&gt;</description>
      <link>http://artyprog.blogspot.com/2009/07/beginning-f-card-tricks.html</link>
      <author>Salvatore</author>
      <pubDate>Sat, 11 Jul 2009 00:21:00 GMT</pubDate>
    </item>
    <item>
      <title>Mastermind F# WPF Game Sample</title>
      <description>&lt;a rel="nofollow" target="_blank" href="http://www.trelford.com/blog/post/Mastermind-F-WPF-Game-Sample.aspx"&gt;http://www.trelford.com/blog/post/Mastermind-F-WPF-Game-Sample.aspx&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10811141-1194798249481391787?l=artyprog.blogspot.com'/&gt;&lt;/div&gt;&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247311020"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247311020" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/HXZF2TdARjr2p_vWOuQpH8q1Ovg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HXZF2TdARjr2p_vWOuQpH8q1Ovg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/HXZF2TdARjr2p_vWOuQpH8q1Ovg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HXZF2TdARjr2p_vWOuQpH8q1Ovg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=-1PUugih_OQ:2pWE-I7lutM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=-1PUugih_OQ:2pWE-I7lutM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=-1PUugih_OQ:2pWE-I7lutM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=-1PUugih_OQ:2pWE-I7lutM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=-1PUugih_OQ:2pWE-I7lutM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=-1PUugih_OQ:2pWE-I7lutM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=-1PUugih_OQ:2pWE-I7lutM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/-1PUugih_OQ" height="1" width="1"/&gt;</description>
      <link>http://artyprog.blogspot.com/2009/07/mastermind-f-wpf-game-sample.html</link>
      <author>Salvatore</author>
      <pubDate>Sat, 11 Jul 2009 00:17:00 GMT</pubDate>
    </item>
    <item>
      <title>How to Write XNA Game Studio Express Games</title>
      <description>&lt;a rel="nofollow" target="_blank" href="http://grammerjack.spaces.live.com/blog/cns!F2629C772A178A7C!156.entry"&gt;http://grammerjack.spaces.live.com/blog/cns!F2629C772A178A7C!156.entry&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10811141-8700284756177438657?l=artyprog.blogspot.com'/&gt;&lt;/div&gt;&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247310900"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247310900" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/FO1T_pIPrYaWqWc7rTgyoDL3_m0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FO1T_pIPrYaWqWc7rTgyoDL3_m0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/FO1T_pIPrYaWqWc7rTgyoDL3_m0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FO1T_pIPrYaWqWc7rTgyoDL3_m0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=0hjRG_GzYQQ:tfw0FKT3hTI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=0hjRG_GzYQQ:tfw0FKT3hTI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=0hjRG_GzYQQ:tfw0FKT3hTI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=0hjRG_GzYQQ:tfw0FKT3hTI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=0hjRG_GzYQQ:tfw0FKT3hTI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=0hjRG_GzYQQ:tfw0FKT3hTI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=0hjRG_GzYQQ:tfw0FKT3hTI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/0hjRG_GzYQQ" height="1" width="1"/&gt;</description>
      <link>http://artyprog.blogspot.com/2009/07/how-to-write-xna-game-studio-express.html</link>
      <author>Salvatore</author>
      <pubDate>Sat, 11 Jul 2009 00:15:00 GMT</pubDate>
    </item>
    <item>
      <title>Learning WPF through F#, and vice versa, by John Liao</title>
      <description>&lt;a rel="nofollow" target="_blank" href="http://blogs.msdn.com/dsyme/archive/2008/01/05/learning-wpf-through-f-and-vice-versa-by-john-liao.aspx"&gt;http://blogs.msdn.com/dsyme/archive/2008/01/05/learning-wpf-through-f-and-vice-versa-by-john-liao.aspx&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10811141-3369426936646590015?l=artyprog.blogspot.com'/&gt;&lt;/div&gt;&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247310720"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247310720" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/eG_Tg8vf3tRnME4KKFaTVo4FZyM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/eG_Tg8vf3tRnME4KKFaTVo4FZyM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/eG_Tg8vf3tRnME4KKFaTVo4FZyM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/eG_Tg8vf3tRnME4KKFaTVo4FZyM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=w2eOFPiusBE:MeK4B5xULXQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=w2eOFPiusBE:MeK4B5xULXQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=w2eOFPiusBE:MeK4B5xULXQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=w2eOFPiusBE:MeK4B5xULXQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=w2eOFPiusBE:MeK4B5xULXQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=w2eOFPiusBE:MeK4B5xULXQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=w2eOFPiusBE:MeK4B5xULXQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/w2eOFPiusBE" height="1" width="1"/&gt;</description>
      <link>http://artyprog.blogspot.com/2009/07/learning-wpf-through-f-and-vice-versa.html</link>
      <author>Salvatore</author>
      <pubDate>Sat, 11 Jul 2009 00:12:00 GMT</pubDate>
    </item>
    <item>
      <title>Exploring F# with Conway’s Game of Life</title>
      <description>&lt;a rel="nofollow" target="_blank" href="http://blogs.vertigo.com/personal/rtaylor/Blog/Lists/Posts/Post.aspx?ID=8"&gt;http://blogs.vertigo.com/personal/rtaylor/Blog/Lists/Posts/Post.aspx?ID=8&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10811141-3582920395849550155?l=artyprog.blogspot.com'/&gt;&lt;/div&gt;&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247310600"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247310600" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6fElhlVs-xLF6BApQA1Q-VZQgl0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6fElhlVs-xLF6BApQA1Q-VZQgl0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6fElhlVs-xLF6BApQA1Q-VZQgl0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6fElhlVs-xLF6BApQA1Q-VZQgl0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=hZnUZ9LCKaE:WusFKOsLCWU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=hZnUZ9LCKaE:WusFKOsLCWU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=hZnUZ9LCKaE:WusFKOsLCWU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=hZnUZ9LCKaE:WusFKOsLCWU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=hZnUZ9LCKaE:WusFKOsLCWU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=hZnUZ9LCKaE:WusFKOsLCWU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=hZnUZ9LCKaE:WusFKOsLCWU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/hZnUZ9LCKaE" height="1" width="1"/&gt;</description>
      <link>http://artyprog.blogspot.com/2009/07/exploring-f-with-conways-game-of-life.html</link>
      <author>Salvatore</author>
      <pubDate>Sat, 11 Jul 2009 00:10:00 GMT</pubDate>
    </item>
    <item>
      <title>Simple F# Game using WPF</title>
      <description>&lt;a rel="nofollow" target="_blank" href="http://blogs.msdn.com/chrsmith/archive/2008/09/04/simple-f-game-using-wpf.aspx"&gt;http://blogs.msdn.com/chrsmith/archive/2008/09/04/simple-f-game-using-wpf.aspx&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10811141-7527727353288964836?l=artyprog.blogspot.com'/&gt;&lt;/div&gt;&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247310420"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247310420" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/44QYbhbuq7JqoIDCb7B5z7yg8x4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/44QYbhbuq7JqoIDCb7B5z7yg8x4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/44QYbhbuq7JqoIDCb7B5z7yg8x4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/44QYbhbuq7JqoIDCb7B5z7yg8x4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=2M2GX3qIfPA:TKriYCTdE84:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=2M2GX3qIfPA:TKriYCTdE84:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=2M2GX3qIfPA:TKriYCTdE84:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=2M2GX3qIfPA:TKriYCTdE84:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=2M2GX3qIfPA:TKriYCTdE84:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=2M2GX3qIfPA:TKriYCTdE84:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=2M2GX3qIfPA:TKriYCTdE84:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/2M2GX3qIfPA" height="1" width="1"/&gt;</description>
      <link>http://artyprog.blogspot.com/2009/07/simple-f-game-using-wpf.html</link>
      <author>Salvatore</author>
      <pubDate>Sat, 11 Jul 2009 00:07:00 GMT</pubDate>
    </item>
    <item>
      <title>F# FOR GAME DEVELOPMENT</title>
      <description>&lt;a rel="nofollow" target="_blank" href="http://sharp-gamedev.blogspot.com/2008/09/hello-world.html"&gt;http://sharp-gamedev.blogspot.com/2008/09/hello-world.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/10811141-1495897012921544700?l=artyprog.blogspot.com'/&gt;&lt;/div&gt;&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247309940"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247309940" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/7DHmou_FAyPmXlmKLizGSQWxzw4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7DHmou_FAyPmXlmKLizGSQWxzw4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/7DHmou_FAyPmXlmKLizGSQWxzw4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7DHmou_FAyPmXlmKLizGSQWxzw4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=FQ-oeiDa9Mw:OQSEPgfXwVw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=FQ-oeiDa9Mw:OQSEPgfXwVw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=FQ-oeiDa9Mw:OQSEPgfXwVw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=FQ-oeiDa9Mw:OQSEPgfXwVw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=FQ-oeiDa9Mw:OQSEPgfXwVw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=FQ-oeiDa9Mw:OQSEPgfXwVw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=FQ-oeiDa9Mw:OQSEPgfXwVw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/FQ-oeiDa9Mw" height="1" width="1"/&gt;</description>
      <link>http://artyprog.blogspot.com/2009/07/f-for-game-development.html</link>
      <author>Salvatore</author>
      <pubDate>Fri, 10 Jul 2009 23:59:00 GMT</pubDate>
    </item>
    <item>
      <title>LAgent: an agent framework in F# – part VII – An auction application</title>
      <description>&lt;p&gt;Here is an application that uses the framework we have been creating. It is an auction application and it is described in more detail &lt;a rel="nofollow" target="_blank" href="http://codebetter.com/blogs/matthew.podwysocki/archive/2009/05/20/f-actors-revisited.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Let’s go through it.&lt;/p&gt; &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;type &lt;/span&gt;AuctionMessage = | Offer &lt;span style="color:blue;"&gt;of &lt;/span&gt;int * AsyncAgent &lt;span style="color:green;"&gt;// Make a bid &lt;/span&gt;| Inquire &lt;span style="color:blue;"&gt;of &lt;/span&gt;AsyncAgent &lt;span style="color:green;"&gt;// Check the status
&lt;/span&gt;&lt;span style="color:blue;"&gt;and &lt;/span&gt;AuctionReply = | StartBidding | Status &lt;span style="color:blue;"&gt;of &lt;/span&gt;int * DateTime &lt;span style="color:green;"&gt;// Asked sum and expiration &lt;/span&gt;| BestOffer &lt;span style="color:green;"&gt;// Ours is the best offer &lt;/span&gt;| BeatenOffer &lt;span style="color:blue;"&gt;of &lt;/span&gt;int &lt;span style="color:green;"&gt;// Yours is beaten by another offer &lt;/span&gt;| AuctionConcluded &lt;span style="color:blue;"&gt;of &lt;/span&gt;&lt;span style="color:green;"&gt;// Auction concluded &lt;/span&gt;AsyncAgent * AsyncAgent | AuctionFailed &lt;span style="color:green;"&gt;// Failed without any bids &lt;/span&gt;| AuctionOver &lt;span style="color:green;"&gt;// Bidding is closed &lt;/span&gt;&lt;span style="color:blue;"&gt;let &lt;/span&gt;timeToShutdown = 3000
&lt;span style="color:blue;"&gt;let &lt;/span&gt;bidIncrement = 10 &lt;/pre&gt; &lt;p&gt;This is the format of the messages that the clients can send and the action agent can reply to. F# is really good at this sort of thing. First, we need an auction agent:&lt;/p&gt; &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;let &lt;/span&gt;auctionAgent seller minBid closing = &lt;span style="color:blue;"&gt;let &lt;/span&gt;agent = spawnAgent (&lt;span style="color:blue;"&gt;fun &lt;/span&gt;msg (isConcluded, maxBid, maxBidder) &lt;span style="color:blue;"&gt;-&amp;gt; match &lt;/span&gt;msg &lt;span style="color:blue;"&gt;with &lt;/span&gt;| Offer (_, client) &lt;span style="color:blue;"&gt;when &lt;/span&gt;isConcluded &lt;span style="color:blue;"&gt;-&amp;gt; &lt;/span&gt;client &amp;lt;-- AuctionOver (isConcluded, maxBid, maxBidder) | Offer(bid, client) &lt;span style="color:blue;"&gt;when &lt;/span&gt;not(isConcluded) &lt;span style="color:blue;"&gt;-&amp;gt; if &lt;/span&gt;bid &amp;gt;= maxBid + bidIncrement &lt;span style="color:blue;"&gt;then if &lt;/span&gt;maxBid &amp;gt;= minBid &lt;span style="color:blue;"&gt;then &lt;/span&gt;maxBidder &amp;lt;-- BeatenOffer bid client &amp;lt;-- BestOffer (isConcluded, bid, client) &lt;span style="color:blue;"&gt;else &lt;/span&gt;client &amp;lt;-- BeatenOffer maxBid (isConcluded, maxBid, maxBidder) | Inquire client &lt;span style="color:blue;"&gt;-&amp;gt; &lt;/span&gt;client &amp;lt;-- Status(maxBid, closing) (isConcluded, maxBid, maxBidder)) (&lt;span style="color:blue;"&gt;false&lt;/span&gt;, (minBid - bidIncrement), spawnWorker (&lt;span style="color:blue;"&gt;fun &lt;/span&gt;_ &lt;span style="color:blue;"&gt;-&amp;gt; &lt;/span&gt;())) &lt;/pre&gt; &lt;p&gt;Notice that, if the action is concluded, the agent replies to offers by sending an &lt;em&gt;AuctionOver&lt;/em&gt; message. If the auction is still open, then, in case the bid is higher than the max, it sets a new max and notify the two parties involved; otherwise it notifies the bidder that the offer wasn’t successful. Also you can ask for the status of the auction.&lt;/p&gt; &lt;p&gt;This is what the code above says. Maybe the code is simpler than words. Anyhow, we need to treat the case where no message is received for some amount of time.&lt;/p&gt; &lt;pre class="code"&gt;agent &amp;lt;-- SetTimeoutHandler (closing - DateTime.Now).Milliseconds (&lt;span style="color:blue;"&gt;fun &lt;/span&gt;(isConcluded: bool, maxBid, maxBidder) &lt;span style="color:blue;"&gt;-&amp;gt; if &lt;/span&gt;maxBid &amp;gt;= minBid &lt;span style="color:blue;"&gt;then let &lt;/span&gt;reply = AuctionConcluded(seller, maxBidder) maxBidder &amp;lt;-- reply seller &amp;lt;-- reply &lt;span style="color:blue;"&gt;else &lt;/span&gt;seller &amp;lt;-- AuctionFailed agent &amp;lt;-- SetTimeoutHandler timeToShutdown (&lt;span style="color:blue;"&gt;fun &lt;/span&gt;(_:bool, _:int,_:AsyncAgent) &lt;span style="color:blue;"&gt;-&amp;gt; &lt;/span&gt;StopProcessing) ContinueProcessing (&lt;span style="color:blue;"&gt;true&lt;/span&gt;, maxBid, maxBidder)) agent &lt;/pre&gt; &lt;p&gt;We start by waiting for the amount of time to the closing of the auction. If we get no messages, then two things might happen: we have an offer that is more than the minimum or we don’t. If we do, we tell everyone that it’s finished. Otherwise, we tell the seller that its item wasn’t successful.&amp;#160; In any case, we prepare the agent to shutdown by setting its next timeout to be &lt;em&gt;timeoutToShutdown&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;It is interesting that we set the timeout handler inside the timeout handler. This is not a problem because of the nature of message processing (aka it processes one message at the time).&lt;/p&gt; &lt;p&gt;We then need a bunch of of symbols …&lt;/p&gt; &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;module &lt;/span&gt;Auction = &lt;span style="color:blue;"&gt;let &lt;/span&gt;random = &lt;span style="color:blue;"&gt;new &lt;/span&gt;Random() &lt;span style="color:blue;"&gt;let &lt;/span&gt;minBid = 100 &lt;span style="color:blue;"&gt;let &lt;/span&gt;closing = DateTime.Now.AddMilliseconds 10000. &lt;span style="color:blue;"&gt;let &lt;/span&gt;seller = spawnWorker (&lt;span style="color:blue;"&gt;fun &lt;/span&gt;(msg:AuctionReply) &lt;span style="color:blue;"&gt;-&amp;gt; &lt;/span&gt;()) &lt;span style="color:blue;"&gt;let &lt;/span&gt;auction = auctionAgent seller minBid closing&lt;/pre&gt; &lt;p&gt;Not a very smart seller we have here … Next up is our definition of a client.&lt;/p&gt; &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;let rec &lt;/span&gt;c = spawnAgent ( &lt;span style="color:blue;"&gt;fun &lt;/span&gt;msg (max, current) &lt;span style="color:blue;"&gt;-&amp;gt; let &lt;/span&gt;processBid (aMax, aCurrent) = &lt;span style="color:blue;"&gt;if &lt;/span&gt;aMax &amp;gt;= top &lt;span style="color:blue;"&gt;then &lt;/span&gt;log &lt;span style="color:maroon;"&gt;"too high for me" &lt;/span&gt;(aMax, aCurrent) &lt;span style="color:blue;"&gt;elif &lt;/span&gt;aCurrent &amp;lt; aMax &lt;span style="color:blue;"&gt;then let &lt;/span&gt;aCurrent = aMax + increment Thread.Sleep (1 + random.Next 1000) auction &amp;lt;-- Offer(aCurrent, c) (aMax, aCurrent) &lt;span style="color:blue;"&gt;else &lt;/span&gt;(aMax, aCurrent) &lt;span style="color:blue;"&gt;match &lt;/span&gt;msg &lt;span style="color:blue;"&gt;with &lt;/span&gt;| StartBidding &lt;span style="color:blue;"&gt;-&amp;gt; &lt;/span&gt;auction &amp;lt;-- Inquire c (max, current) | Status(maxBid,_) &lt;span style="color:blue;"&gt;-&amp;gt; &lt;/span&gt;log &amp;lt;| sprintf &lt;span style="color:maroon;"&gt;"status(%d)" &lt;/span&gt;maxBid &lt;span style="color:blue;"&gt;let &lt;/span&gt;s = processBid (maxBid, current) c &amp;lt;-- SetTimeoutHandler timeToShutdown (&lt;span style="color:blue;"&gt;fun &lt;/span&gt;_ &lt;span style="color:blue;"&gt;-&amp;gt; &lt;/span&gt;StopProcessing) s | BestOffer &lt;span style="color:blue;"&gt;-&amp;gt; &lt;/span&gt;log &amp;lt;| sprintf &lt;span style="color:maroon;"&gt;"bestOffer(%d)" &lt;/span&gt;current processBid(max, current) | BeatenOffer maxBid &lt;span style="color:blue;"&gt;-&amp;gt; &lt;/span&gt;log &amp;lt;| sprintf &lt;span style="color:maroon;"&gt;"beatenOffer(%d)" &lt;/span&gt;maxBid processBid(maxBid, current) | AuctionConcluded(seller, maxBidder) &lt;span style="color:blue;"&gt;-&amp;gt; &lt;/span&gt;log &lt;span style="color:maroon;"&gt;"auctionConcluded" &lt;/span&gt;c &amp;lt;-- Stop (max, current) | AuctionOver &lt;span style="color:blue;"&gt;-&amp;gt; &lt;/span&gt;log &lt;span style="color:maroon;"&gt;"auctionOver" &lt;/span&gt;c &amp;lt;-- Stop (max, current)) (0,0)
c&lt;/pre&gt; &lt;p&gt;Something that I like about agents is the fact that you need to understand just small snippets of code at the time. For example, you can read the processing for BestOffer and figure out if it makes sense.&amp;#160; I have an easy time personalizing them as in : “Ok, the guy just got a notification that there has been a better offer, what is he going to do next?”.&lt;/p&gt; &lt;p&gt;The code should be self explanatory for the most part. In essence, if you can offer more, do it otherwise wait for the auction to end. I’m not even sure the processing is completely right. I confess I’m just trying to do the same as Matthews code from the link above.&lt;/p&gt; &lt;p&gt;We can then start up the whole thing and enjoy the cool output.&lt;/p&gt; &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;open &lt;/span&gt;Auction (client 1 20 200) &amp;lt;-- StartBidding
(client 2 10 300) &amp;lt;-- StartBidding
(client 3 30 150) &amp;lt;-- StartBidding
Console.ReadLine() |&amp;gt; ignore &lt;/pre&gt; &lt;p&gt;Now for the nasty part. Implementing the framework.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9682539" width="1" height="1"&gt;&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247267640"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247267640" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Bu5iTqAV9Z4VNYbkzwuF8WG0FOQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Bu5iTqAV9Z4VNYbkzwuF8WG0FOQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Bu5iTqAV9Z4VNYbkzwuF8WG0FOQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Bu5iTqAV9Z4VNYbkzwuF8WG0FOQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=g8v8JqeI4RI:UqZ-pCgQpOI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=g8v8JqeI4RI:UqZ-pCgQpOI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=g8v8JqeI4RI:UqZ-pCgQpOI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=g8v8JqeI4RI:UqZ-pCgQpOI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=g8v8JqeI4RI:UqZ-pCgQpOI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=g8v8JqeI4RI:UqZ-pCgQpOI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=g8v8JqeI4RI:UqZ-pCgQpOI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/g8v8JqeI4RI" height="1" width="1"/&gt;</description>
      <link>http://blogs.msdn.com/lucabol/archive/2009/07/10/lagent-an-agent-framework-in-f-part-vii-an-auction-application.aspx</link>
      <pubDate>Fri, 10 Jul 2009 12:14:00 GMT</pubDate>
    </item>
    <item>
      <title>Modeling DSLs with F# and Units of Measure</title>
      <description>&lt;p&gt;Very recently on &lt;a rel="nofollow" target="_blank" href="http://lambda-the-ultimate.org/node/3483"&gt;Lambda the Ultimate&lt;/a&gt;, they had a really good post describing &lt;a rel="nofollow" target="_blank" href="http://www.st.cs.ru.nl/papers/2008/achp08-FDPE08-SoccerFun.pdf"&gt;Soccer-Fun, a way to teach functional programming (pdf)&lt;/a&gt;.&amp;nbsp; The premise is very simple and is described as the following:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;...a domain specific language for simulating football. ... We have used Soccer-Fun in teaching during the past four years. We have also experience in using Soccer-Fun for pupils in secondary education. ... It engages students to problem solving with functional programming because it allows them to compete at several disciplines: the best performing football team can become champion of a tournament; the best written code can be awarded with a prize; students can be judged on the algorithms used. This enables every student to participate and perform at her favourite skill. ... It can be implemented in any functional programming language that supports some kind of windowing toolkit.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt; &lt;p&gt;This serves as an introductory course in functional programming called “Abstraction and Composition in Programming”.&amp;nbsp; This course covers what you might consider classic functional programming materal including basic types, algebraic data types, high order functions, overloading, recursion and so on.&amp;nbsp; But what’s interesting as well is that it has been applied to secondary school aged students as well.&amp;nbsp; A course such as this which engages through the use of a well known subject such as soccer or football, depending on your nationality of course.&amp;nbsp; &lt;/p&gt; &lt;p&gt;Although the paper discussed here is implemented using the &lt;a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Clean_programming_language"&gt;Clean programming language&lt;/a&gt;, which has striking similarities to Haskell, another purely functional programming language.&amp;nbsp; As I read the document, I wondered how F# as a language would fare to implement such a DSL, especially with the use of Units of Measure.&lt;/p&gt; &lt;h2&gt;Introducing Units of Measure&lt;/h2&gt; &lt;p&gt;One feature of F# that was introduced in the September 2008 CTP release of F# was static checking and inference of Units of Measure.&amp;nbsp;&amp;nbsp; The idea is that we have defined&amp;nbsp; in the F# libraries the &lt;a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/International_System_of_Units"&gt;International System of Units (SI)&lt;/a&gt; such as meters, seconds, and kilograms and apply them in ways that they are statically checked and inferred without much ceremony, but as well to create and apply our own such as feet, gallons or whatever we so choose.&lt;/p&gt; &lt;p&gt;For example, I could specify my weight in pounds in F# Interactive as the following:&lt;/p&gt; &lt;div style="margin:0px;padding:0px;display:inline;float:none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:aa32fb50-ac7d-4526-ae16-d8b889ec292f" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow:auto;background-color:rgb(255, 255, 255);"&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; [&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;Measure&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;] &lt;/span&gt;&lt;span style="color:rgb(0, 0, 255);"&gt;type&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; lb;; [&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;Measure&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;]
&lt;/span&gt;&lt;span style="color:rgb(0, 0, 255);"&gt;type&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; lb &lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color:rgb(0, 0, 255);"&gt;let&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; weight &lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color:rgb(128, 0, 128);"&gt;180.0&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;lb&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;;; &lt;/span&gt;&lt;span style="color:rgb(0, 0, 255);"&gt;val&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; weight : float&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;lb&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color:rgb(128, 0, 128);"&gt;180.0&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;As you can tell from above, it inferred that my weight is in fact a floating point in pounds, and that I weight approximately 180.&amp;nbsp; What’s powerful about this concept is that I cannot then compare it with just another float, it must be of the same type as we note below:&lt;/p&gt; &lt;div style="margin:0px;padding:0px;display:inline;float:none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:ec4851e8-130b-4ab8-ab17-119214af77bc" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow:auto;background-color:rgb(255, 255, 255);"&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; weight &lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color:rgb(128, 0, 128);"&gt;180.0&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;;; weight &lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color:rgb(128, 0, 128);"&gt;180&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;.;; &lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;---------^^^^&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; stdin(&lt;/span&gt;&lt;span style="color:rgb(128, 0, 128);"&gt;79&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;,&lt;/span&gt;&lt;span style="color:rgb(128, 0, 128);"&gt;10&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;): error FS0001: This expression has &lt;/span&gt;&lt;span style="color:rgb(0, 0, 255);"&gt;type&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; float
but is here used &lt;/span&gt;&lt;span style="color:rgb(0, 0, 255);"&gt;with&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color:rgb(0, 0, 255);"&gt;type&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; float&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;lb&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Andrew Kennedy, one of the forces behind this effort and researcher at Microsoft Research Cambridge, blogged about this in a multi-part series covering:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://blogs.msdn.com/andrewkennedy/archive/2008/08/29/units-of-measure-in-f-part-one-introducing-units.aspx"&gt;Part 1 – Introducing Units&lt;/a&gt; &lt;/li&gt; &lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://blogs.msdn.com/andrewkennedy/archive/2008/09/02/units-of-measure-in-f-part-two-unit-conversions.aspx"&gt;Part 2 – Unit Conversions&lt;/a&gt; &lt;/li&gt; &lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://blogs.msdn.com/andrewkennedy/archive/2008/09/04/units-of-measure-in-f-part-three-generic-units.aspx"&gt;Part 3 – Generic Units&lt;/a&gt; &lt;/li&gt; &lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://blogs.msdn.com/andrewkennedy/archive/2009/06/09/units-of-measure-in-f_2300_-part-four-parameterized-types.aspx"&gt;Part 4 – Parameterized Types&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt; &lt;p&gt;Now that you’re back, you might ask how this applies in this situation.&amp;nbsp; Can we use this to our advantage when modeling such things as basic elements of soccer using units of measure?&lt;/p&gt; &lt;h2&gt;Applying to Soccer Fun&lt;/h2&gt; &lt;p&gt;Indeed many of the calculations required for Soccer Fun do require a bit of hard type units.&amp;nbsp; For example, let’s look at how to model such things as specifying the size of the football field.&amp;nbsp; As not all fields are the same size, we can model it in meters such as the following.&amp;nbsp; We’ll note that F# already defines the &lt;a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/International_System_of_Units"&gt;International System of Units (SI)&lt;/a&gt; in the SI module in F# in the FSharp PowerPack assembly.&amp;nbsp; Using F# Interactive, we can get up and running to use these standard measurements by doing the following:&lt;/p&gt; &lt;div style="margin:0px;padding:0px;display:inline;float:none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:329baacd-2765-4f09-86a7-0c0e2f9ff3e6" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow:auto;background-color:rgb(255, 255, 255);"&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; #r &lt;/span&gt;&lt;span style="color:rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color:rgb(128, 0, 0);"&gt;FSharp.PowerPack.dll&lt;/span&gt;&lt;span style="color:rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;-&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color:rgb(0, 0, 255);"&gt;open&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; Microsoft.FSharp.Math.SI;;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Now getting back to our solution, we can now specify our field dimensions as the following:&lt;/p&gt; &lt;div style="margin:0px;padding:0px;display:inline;float:none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:5ba26aec-8562-4053-ad21-00862a3ec7ea" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow:auto;background-color:rgb(255, 255, 255);"&gt;&lt;span style="color:rgb(0, 0, 255);"&gt;type&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; Meter &lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; float&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;m&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color:rgb(0, 0, 255);"&gt;type&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; FieldWidth &lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; Meter
&lt;/span&gt;&lt;span style="color:rgb(0, 0, 255);"&gt;type&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; FieldLength &lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; Meter
&lt;/span&gt;&lt;span style="color:rgb(0, 0, 255);"&gt;type&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; FootballField &lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; { Width : FieldWidth; Length : FieldLength }&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;I followed the intent closely of the paper to create type aliases for both the Meter as well as the field’s length and width.&amp;nbsp; We can then create a record type to hold both our width and length of our field in floating point meters.&lt;/p&gt; &lt;p&gt;Another example is that both players and the ball both travel at a certain speed and in a certain direction.&amp;nbsp; We need the ability to not only calculate the speed along the surface, but also the speed above the surface in a full three dimensions as well as the direction.&amp;nbsp; We might implement this as the following:&lt;/p&gt; &lt;div style="margin:0px;padding:0px;display:inline;float:none;" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:cc06fabe-f283-4b3e-b429-91b51ef63dea" class="wlWriterEditableSmartContent"&gt;&lt;pre style="overflow:auto;background-color:rgb(255, 255, 255);"&gt;&lt;span style="color:rgb(0, 0, 255);"&gt;type&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; Radian &lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; float
&lt;/span&gt;&lt;span style="color:rgb(0, 0, 255);"&gt;type&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; Angle &lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; Radian &lt;/span&gt;&lt;span style="color:rgb(0, 0, 255);"&gt;type&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; Velocity &lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; float&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;m&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;/&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;s&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;
&lt;/span&gt;&lt;span style="color:rgb(0, 0, 255);"&gt;type&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; Speed &lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; { Direction : Angle; Velocity : Velocity }
&lt;/span&gt;&lt;span style="color:rgb(0, 0, 255);"&gt;type&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; Speed3D &lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color:rgb(0, 0, 0);"&gt; { Speed2D : Speed; Speed3D : Velocity }&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Above, I described that our angles will be calculated in radians, and our velocity will be calculated in meters per second.&amp;nbsp; With those two data types in hand, we can then store the speed of the players using the Speed type and the ball using the Speed3D type as it has a tendency to travel in three dimensions whereas the players tend to travel on only two.&lt;/p&gt; &lt;h2&gt;Conclusion&lt;/h2&gt; &lt;p&gt;This of course is only a start to look at such a concept for how to implement this in F#, but it gives us another tool in our belt to model our data much more accurately in the domain in which we are in.&amp;nbsp; The conciseness of the language makes it an ideal candidate for scientific DSLs where such units of measure are important, but as we can see from this example, it could even apply to the general physics of game play.&lt;/p&gt;&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247198400"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247198400" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5DcDVx3esgyOZtrkPUEE1tQe0HM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5DcDVx3esgyOZtrkPUEE1tQe0HM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5DcDVx3esgyOZtrkPUEE1tQe0HM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5DcDVx3esgyOZtrkPUEE1tQe0HM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=XKd8e2cNBNc:JGvknDfOdxI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=XKd8e2cNBNc:JGvknDfOdxI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=XKd8e2cNBNc:JGvknDfOdxI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=XKd8e2cNBNc:JGvknDfOdxI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=XKd8e2cNBNc:JGvknDfOdxI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=XKd8e2cNBNc:JGvknDfOdxI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=XKd8e2cNBNc:JGvknDfOdxI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/XKd8e2cNBNc" height="1" width="1"/&gt;</description>
      <link>http://weblogs.asp.net/podwysocki/archive/2009/07/10/modeling-dsls-with-f-and-units-of-measure.aspx</link>
      <pubDate>Thu, 09 Jul 2009 17:00:00 GMT</pubDate>
    </item>
    <item>
      <title>Active Patterns (F#)</title>
      <description>&lt;img src="http://mschnlnine.vo.llnwd.net/d1/ch9/0/3/1/7/7/4/ActivePatterns_small_ch9.png" border="0"/&gt;&lt;p&gt;In this video, programming writer, Gordon Hogenson, continues the discussion of patterns by talking about active patterns, which you can use to customize and extend F#’s pattern matching capabilities. Active patterns are an amazingly flexible language feature, and in this video we just scratch the surface of what can be done with them. You can learn more in the topic: &lt;a rel="nofollow" target="_blank" href="http://msdn.microsoft.com/en-us/library/dd233248(VS.100).aspx"&gt;Active Patterns&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Gordon would also like to thank Chris Smith and Brian McNamara, of the F# team, for giving him some ideas for how to use active patterns. Some similar examples to those in the video are discussed in F# team blog postings, such as in &lt;a rel="nofollow" target="_blank" href="http://blogs.msdn.com/chrsmith/archive/2008/02/21/Introduction-to-F_2300_-Active-Patterns.aspx"&gt;Chris Smith’s blog posting on active patterns&lt;/a&gt;. For those interested in exploring further, you can read a &lt;a rel="nofollow" target="_blank" href="http://blogs.msdn.com/dsyme/archive/2007/04/07/draft-paper-on-f-active-patterns.aspx"&gt;paper on active patterns by Don Syme, James Margetson, and Gregory Nemerov&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Kathleen McGrath&lt;br /&gt;
Visual Studio User Education&lt;br /&gt;
&lt;a rel="nofollow" target="_blank" href="http://blogs.msdn.com/kathleen/"&gt;http://blogs.msdn.com/kathleen/&lt;/a&gt;&lt;/p&gt;&lt;img src="http://channel9.msdn.com/477130/WebViewBug.aspx?EVT=0" height="1" width="1" alt=""/&gt;&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247198340"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247198340" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Nrh3TlHqDSob1fD7s5v6_QvwdzA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Nrh3TlHqDSob1fD7s5v6_QvwdzA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Nrh3TlHqDSob1fD7s5v6_QvwdzA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Nrh3TlHqDSob1fD7s5v6_QvwdzA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=nBVOc26fiRE:NZxlT-uOicA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=nBVOc26fiRE:NZxlT-uOicA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=nBVOc26fiRE:NZxlT-uOicA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=nBVOc26fiRE:NZxlT-uOicA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=nBVOc26fiRE:NZxlT-uOicA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=nBVOc26fiRE:NZxlT-uOicA:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=nBVOc26fiRE:NZxlT-uOicA:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/nBVOc26fiRE" height="1" width="1"/&gt;</description>
      <link>http://channel9.msdn.com/posts/kmcgrath/Active-Patterns-F/</link>
      <pubDate>Thu, 09 Jul 2009 16:59:00 GMT</pubDate>
    </item>
    <item>
      <title>Rapid prototyping of DSLs in F# - Part III</title>
      <description>The third part of "Rapid prototyping of DSLs in F#" presents the semantic checker for Simply, a small programming language with functions and expressions.&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247189500"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247189500" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/dJ9I3Fqux87BDfv2-BZmmbhbeJg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dJ9I3Fqux87BDfv2-BZmmbhbeJg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/dJ9I3Fqux87BDfv2-BZmmbhbeJg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dJ9I3Fqux87BDfv2-BZmmbhbeJg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=115NsiRj63I:aP_Lfqy0EH8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=115NsiRj63I:aP_Lfqy0EH8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=115NsiRj63I:aP_Lfqy0EH8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=115NsiRj63I:aP_Lfqy0EH8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=115NsiRj63I:aP_Lfqy0EH8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=115NsiRj63I:aP_Lfqy0EH8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=115NsiRj63I:aP_Lfqy0EH8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/115NsiRj63I" height="1" width="1"/&gt;</description>
      <link>http://www.intellifactory.com/blogs/adam.granicz/2009/7/10/Rapid-prototyping-of-DSLs-in-F!sharp!---Part-III.article</link>
      <pubDate>Thu, 09 Jul 2009 14:31:40 GMT</pubDate>
    </item>
    <item>
      <title>not an f# post</title>
      <description>Yes, ladies and gentlemen, i have a day job, and sometimes i must put down the f# koolade and do real work. well... maybe not "real" work per se, but... Anyway, to that end...
I've spent some time scratching my head about the best way to integrate a validation mechanism into bistro. Now... there's not an [...]&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247157975"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247157975" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/2r-PL3FN2yPn2R6mrXVEBpfPwGM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2r-PL3FN2yPn2R6mrXVEBpfPwGM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/2r-PL3FN2yPn2R6mrXVEBpfPwGM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2r-PL3FN2yPn2R6mrXVEBpfPwGM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=LzngfrUUrVo:2O1DKSf_2JE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=LzngfrUUrVo:2O1DKSf_2JE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=LzngfrUUrVo:2O1DKSf_2JE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=LzngfrUUrVo:2O1DKSf_2JE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=LzngfrUUrVo:2O1DKSf_2JE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=LzngfrUUrVo:2O1DKSf_2JE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=LzngfrUUrVo:2O1DKSf_2JE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/LzngfrUUrVo" height="1" width="1"/&gt;</description>
      <link>http://www.russiantequila.com/wordpress/?p=81</link>
      <category>Uncategorized</category>
      <pubDate>Thu, 09 Jul 2009 05:46:15 GMT</pubDate>
    </item>
    <item>
      <title>Interfaces made convenient by type constraints</title>
      <description>If my previous entry convinced you to make extensive use of interfaces, you may have encountered a problem, namely that calling methods implementing interfaces requires casting:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;let link = new Link("link", config, ...)&lt;br /&gt;// We want to write:&lt;br /&gt;link.Send(data)&lt;br /&gt;// But that does not compile. Instead, we must write:&lt;br /&gt;(link :&amp;gt; ILinkOutput).Send(data)&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The bad news are that there is no work around. The good news is that this situation does not happen to often in practice, as the creator of a link is in general not the user. New instances are often forwarded to other objects or functions, which will see them as ILinkOutput, thus not requiring a cast:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;let register (p : ISender) (l : ILinkOutput) =&lt;br /&gt; p.AddOutputLink(l) // OK: p is an ISender, no need for explicit cast&lt;br /&gt; l.ConnectInputTo(p) // OK: l is an ILinkOutput, no need for explici cast&lt;br /&gt;&lt;br /&gt;let link = new Link(...)&lt;br /&gt;let process = new Process(...)&lt;br /&gt;register process link // OK: process and link automatically upcasted&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Now, what happens if we have a function taking a process and which needs to use two of its interfaces? There are two obvious solutions, which are not so pretty.&lt;br /&gt;&lt;br /&gt;Ugly-ish:&lt;br /&gt;&lt;div class="mycode"&gt;let register (p1 : ISender) (l : Link) (p2 : IReceiver) =&lt;br /&gt; p1.AddOutputLink(l) // Nice&lt;br /&gt; p2.AddInputLink(l) // Nice&lt;br /&gt; (l :&amp;gt; ILinkOutput).ConnectInputTo(p1) // Not so nice&lt;br /&gt; (l :&amp;gt; ILinkInput).ConnectOutputTo(p2) // Not so nice&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Uglier:&lt;br /&gt;&lt;div class="mycode"&gt;let register (p1 : ISender) (l1 : ILinkOutput) (l2 : ILinkOutput) (p2 : IReceiver) =&lt;br /&gt; p1.AddOutputLink(l) // Nice&lt;br /&gt; p2.AddInputLink(l) // Nice&lt;br /&gt; l1.ConnectInputTo(p1) // Nice (is it?)&lt;br /&gt; l2.ConnectOutputTo(p2) // Nice (is it?)&lt;br /&gt;&lt;br /&gt;// Set up two processes communicating with each other.&lt;br /&gt;// As links are uni-directional, use two links.&lt;br /&gt;let p1 = new Process(...)&lt;br /&gt;let p2 = new Process(...)&lt;br /&gt;let link_p1_p2 = new Link(...)&lt;br /&gt;let link_p2_p1 = new Link(...)&lt;br /&gt;&lt;br /&gt;// p1 -&amp;gt; p2&lt;br /&gt;register p1 link_p1_p2 link_p2_p1 p2 // Oops!!!&lt;br /&gt;// p2 -&amp;gt; p1&lt;br /&gt;register p2 link_p2_p1 link_p1_p2 p1 // Oops!!!&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;So many 1s and 2s... We really meant to write:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;// p1 -&amp;gt; p2&lt;br /&gt;register p1 link_p1_p2 link_p1_p2 p2 &lt;br /&gt;// p2 -&amp;gt; p1&lt;br /&gt;register p2 link_p2_p1 link_p2_p1 p1&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The correct solution uses generics and type constraints:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;let register&lt;br /&gt; (p1 : ISender)&lt;br /&gt; (l : 'L&lt;br /&gt; when 'L :&amp;gt; ILinkInput&lt;br /&gt; and 'L :&amp;gt; ILinkOutput)&lt;br /&gt; (p2 : IReceiver) =&lt;br /&gt;&lt;br /&gt; p1.AddOutputLink(l)&lt;br /&gt; p2.AddInputLink(l)&lt;br /&gt; l.ConnectInputTo(p1)&lt;br /&gt; l.ConnectOutputTo(p2)&lt;br /&gt;&lt;br /&gt;// Set up two processes communicating with each other.&lt;br /&gt;// As links are uni-directional, use two links.&lt;br /&gt;let p1 = new Process(...)&lt;br /&gt;let p2 = new Process(...)&lt;br /&gt;let link_p1_p2 = new Link(...)&lt;br /&gt;let link_p2_p1 = new Link(...)&lt;br /&gt;&lt;br /&gt;// p1 -&amp;gt; p2&lt;br /&gt;register p1 link_p1_p2 p2&lt;br /&gt;// p2 -&amp;gt; p1&lt;br /&gt;register p2 link_p2_p1 p1&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Another use of type constraints is for cases when you want to pass lists of ISenders to a function.&lt;br /&gt;&lt;br /&gt;Problem:&lt;br /&gt;&lt;div class="mycode"&gt;let sendAll (ps : ISender list) data =&lt;br /&gt; ps&lt;br /&gt; |&amp;gt; List.iter (fun p -&amp;gt; p.Send(data))&lt;br /&gt;&lt;br /&gt;let p1 = new Process(...)&lt;br /&gt;let p2 = new Process(...)&lt;br /&gt;&lt;br /&gt;sendAll [ (p1 :&amp;gt; ISender) ; (p2 :&amp;gt; ISender) ] data // Blah!&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Solution:&lt;br /&gt;&lt;div class="mycode"&gt;let sendAll (ps : 'S list when 'S :&amp;gt; ISender) data =&lt;br /&gt; ps&lt;br /&gt; |&amp;gt; List.iter (fun p -&amp;gt; p.Send(data))&lt;br /&gt;&lt;br /&gt;let p1 = new Process(...)&lt;br /&gt;let p2 = new Process(...)&lt;br /&gt;&lt;br /&gt;sendAll [ p1; p2 ] data&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Which can also be written:&lt;br /&gt;&lt;div class="mycode"&gt;let sendAll (ps : #ISender list) data =&lt;br /&gt; ps&lt;br /&gt; |&amp;gt; List.iter (fun p -&amp;gt; p.Send(data))&lt;br /&gt;&lt;br /&gt;let p1 = new Process(...)&lt;br /&gt;let p2 = new Process(...)&lt;br /&gt;&lt;br /&gt;sendAll [ p1; p2 ] data&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3205414380859703216-5649326065368690563?l=sharp-gamedev.blogspot.com'/&gt;&lt;/div&gt;&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247071740"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247071740" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/xPZ_E30Vz-JHEiqWnthk0Ii7r70/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xPZ_E30Vz-JHEiqWnthk0Ii7r70/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/xPZ_E30Vz-JHEiqWnthk0Ii7r70/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xPZ_E30Vz-JHEiqWnthk0Ii7r70/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=oXEDKbBijFM:pYBy1CVo9vA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=oXEDKbBijFM:pYBy1CVo9vA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=oXEDKbBijFM:pYBy1CVo9vA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=oXEDKbBijFM:pYBy1CVo9vA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=oXEDKbBijFM:pYBy1CVo9vA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=oXEDKbBijFM:pYBy1CVo9vA:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=oXEDKbBijFM:pYBy1CVo9vA:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/oXEDKbBijFM" height="1" width="1"/&gt;</description>
      <link>http://sharp-gamedev.blogspot.com/2009/07/interfaces-made-convenient-by-type.html</link>
      <author>noreply@blogger.com (Joh.)</author>
      <pubDate>Wed, 08 Jul 2009 05:49:00 GMT</pubDate>
    </item>
    <item>
      <title>Breaking up classes using interfaces</title>
      <description>When I started writing F# programs whose code span over multiple files, I was surprised to see that the &lt;a rel="nofollow" target="_blank" href="http://cs.hubfs.net/forums/thread/11222.aspx"&gt;order&lt;/a&gt; of compilation of these files matters. If the code in file B.fs refers to types or functions in A.fs, then A.fs must be compiled before B.fs.&lt;br /&gt;&lt;br /&gt;Now, what happens if A.fs and B.fs depend on each other? In this case, you have a &lt;a rel="nofollow" target="_blank" href="http://www.sturmnet.org/blog/2008/05/20/f-compiler-considered-too-linear"&gt;problem&lt;/a&gt;. The easy fix is to merge the two files, but this solution does not scale well. Another solution is to break code into smaller pieces, building small "islands" of circular dependencies, which can each be moved into their own file. Easily said, but not so easily said.&lt;br /&gt;&lt;br /&gt;Consider an application involving processes and links. Processes can be executed, and can communicate with each other using unidirectional links.&lt;br /&gt;&lt;br /&gt;The code might look like this:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;type Process(name, config, ...) =&lt;br /&gt; // Construction&lt;br /&gt; ...&lt;br /&gt;&lt;br /&gt; // Methods&lt;br /&gt; // Connection to links&lt;br /&gt; member x.AddInputLink(link : Link) = ...&lt;br /&gt; member x.AddOutputLink(link : Link) = ...&lt;br /&gt;&lt;br /&gt; // Control execution&lt;br /&gt; member x.ExecuteInSomeWay(args) = ...&lt;br /&gt; member x.ExecuteInSomeOtherWay(args) = ...&lt;br /&gt; member x.CheckIsReady() = ...&lt;br /&gt; member x.MarkAsReady() = ...&lt;br /&gt;&lt;br /&gt; // Debugging, and other stuff...&lt;br /&gt; member x.ToggleDebugging(b) = ...&lt;br /&gt; member x.SetDebugOutput(o) = ...&lt;br /&gt; ...&lt;br /&gt;&lt;br /&gt;and type Link(name, config, ...) =&lt;br /&gt; // Construction&lt;br /&gt; ...&lt;br /&gt;&lt;br /&gt; // Methods&lt;br /&gt; // Connection to processes&lt;br /&gt; member x.ConnectOutputTo(p : Process) = ...&lt;br /&gt; member x.ConnectInputTo(p : Process) = ...&lt;br /&gt;&lt;br /&gt; // Read/Write data&lt;br /&gt; member x.Send(data) = ...&lt;br /&gt; member x.Receive() = ...&lt;br /&gt;&lt;br /&gt; // Debugging ...&lt;br /&gt; member x.ToggleDebugging(b) = ...&lt;br /&gt; member x.SetDebugOutput(o) = ...&lt;br /&gt; ...&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;As Process and Link are mutually dependent, their code must be all in one file. That may seem OK at first, but things will become harder to manage as more code is added over time.&lt;br /&gt;&lt;br /&gt;A first solution is to introduce interfaces for Process and Link, simply duplicating all their method signatures, and replace all occurrences of classes Process and Link by their interfaces. The interfaces can be moved to a separate file, which should be shorter, as it contains no code. Classes Process and Link can now each live in separate files.&lt;br /&gt;&lt;br /&gt;Interfaces.fs:&lt;br /&gt;&lt;div class="mycode"&gt;type IProcess =&lt;br /&gt; // Connection to links&lt;br /&gt; abstract AddInputLink : ILink -&amp;gt; ...&lt;br /&gt; abstract AddOutputLink : ILink -&amp;gt; ...&lt;br /&gt;&lt;br /&gt; // Control execution&lt;br /&gt; abstract ExecuteInSomeWay : Args -&amp;gt; ...&lt;br /&gt; ...&lt;br /&gt;&lt;br /&gt; // Debugging, and other stuff...&lt;br /&gt; member x.ToggleDebugging : bool -&amp;gt; unit&lt;br /&gt; ...&lt;br /&gt;&lt;br /&gt;and type ILink =&lt;br /&gt; // Connection to processes&lt;br /&gt; abstract ConnectOutputTo Process -&amp;gt; unit&lt;br /&gt; ...&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Process.fs:&lt;br /&gt;&lt;div class="mycode"&gt;open Interfaces&lt;br /&gt;&lt;br /&gt;type Process(name, config, ...) =&lt;br /&gt; // Construction&lt;br /&gt; ...&lt;br /&gt;&lt;br /&gt; // Interface implementations&lt;br /&gt; interface IProcess with&lt;br /&gt; member x.ExecuteInSomeWay(args) = ...&lt;br /&gt; ...&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Link.fs:&lt;br /&gt;&lt;div class="mycode"&gt;open Interfaces&lt;br /&gt;&lt;br /&gt;type Link(name, config, ...) =&lt;br /&gt; // Construction&lt;br /&gt; ...&lt;br /&gt;&lt;br /&gt; // Interface implementation&lt;br /&gt; interface ILink with&lt;br /&gt; member x.ConnectOutputTo(p : IProcess) = ...&lt;br /&gt; ...&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Still, Interfaces.fs may be excessively long, and we may end up in a situation where all interfaces are defined in one large file. Not very pleasant.&lt;br /&gt;&lt;br /&gt;The next step consists of breaking up the interfaces. The debugging-related methods obviously belong to a IDebugable interface, which need not be concerned with the details of processes and links.&lt;br /&gt;&lt;br /&gt;A process which is connected to the input side of a link has no need to have access to the methods taking care and transferring data from the link to the process, which indicates that ILink could be split in e.g. IInputLink and IOutputLink.&lt;br /&gt;&lt;br /&gt;There is another case of excessive method exposure. Links do not control the execution of processes, that's the task of the scheduler. The final decomposition may look as shown below.&lt;br /&gt;&lt;br /&gt;IActivable.fs:&lt;br /&gt;&lt;div class="mycode"&gt;type IActivable =&lt;br /&gt; abstract CheckIsReady : unit -&amp;gt; bool&lt;br /&gt; abstract MarkAsReady : bool -&amp;gt; unit&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;IExecutable.fs:&lt;br /&gt;&lt;div class="mycode"&gt;type IExecutable =&lt;br /&gt; abstract ExecuteInSomeWay : Args -&amp;gt; ...&lt;br /&gt; abstract ExecuteInSomeOtherWay : Args -&amp;gt; ...&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;InputInterfaces.fs:&lt;br /&gt;&lt;div class="mycode"&gt;type IReceiver =&lt;br /&gt; abstract AddInputLink : ILinkInput -&amp;gt; unit&lt;br /&gt;&lt;br /&gt;and type ILinkInput =&lt;br /&gt; abstract Receive : unit -&amp;gt; Data&lt;br /&gt; abstract ConnectOutputTo : IReceiver -&amp;gt; unit&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;OutputInterfaces.fs:&lt;br /&gt;&lt;div class="mycode"&gt;type ISender =&lt;br /&gt; abstract AddOutputLink : ILinkOutput&lt;br /&gt;&lt;br /&gt;and type ILinkOutput =&lt;br /&gt; abstract Send : Data -&amp;gt; unit&lt;br /&gt; abstract ConnectInputTo : ISender -&amp;gt; unit&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The techniques shown here are by no means specific to F#, and are part of the "proper programming" techniques every object-oriented programmer should know and use. Before using F#, I almost exclusively used interfaces for polymorphism, on "as-needed" basis. The fact is, interfaces are also useful for modular programming.&lt;br /&gt;&lt;br /&gt;Decomposing programs into interfaces and implementation helps writing reusable, readable code. It does have a cost, though, as it requires more typing. As long as keyboards remain cheaper than brains, the benefits should outweigh the costs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3205414380859703216-2784980420112129720?l=sharp-gamedev.blogspot.com'/&gt;&lt;/div&gt;&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247066580"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247066580" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/JMxB-66Kb54TKBN4rhhI2QFJqCs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JMxB-66Kb54TKBN4rhhI2QFJqCs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/JMxB-66Kb54TKBN4rhhI2QFJqCs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JMxB-66Kb54TKBN4rhhI2QFJqCs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=07YheV_QOu8:eOdBp9FQCZo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=07YheV_QOu8:eOdBp9FQCZo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=07YheV_QOu8:eOdBp9FQCZo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=07YheV_QOu8:eOdBp9FQCZo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=07YheV_QOu8:eOdBp9FQCZo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=07YheV_QOu8:eOdBp9FQCZo:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=07YheV_QOu8:eOdBp9FQCZo:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/07YheV_QOu8" height="1" width="1"/&gt;</description>
      <link>http://sharp-gamedev.blogspot.com/2009/07/breaking-up-classes-using-interfaces.html</link>
      <author>noreply@blogger.com (Joh.)</author>
      <pubDate>Wed, 08 Jul 2009 04:23:00 GMT</pubDate>
    </item>
    <item>
      <title>Concurrency on a single thread</title>
      <description>When I wrote my &lt;a rel="nofollow" target="_blank" href="http://sharp-gamedev.blogspot.com/2008/09/tutorial-7-concurrency.html"&gt;article&lt;/a&gt; about concurrency, I did a bit of searching to find out how to use multi-threading in F#. One of the hits was a blog &lt;a rel="nofollow" target="_blank" href="http://cs.hubfs.net/blogs/hell_is_other_languages/archive/2008/08/03/6506.aspx"&gt;entry&lt;/a&gt; on HubFS by gneverov titled "Hell Is Other Languages : Concurrency on a single thread". At that time, I was a bit confused by the article. Why would one want single-threaded concurrency when we already had multi-threaded concurrency? Part of the answer lies in reactive programming.&lt;br /&gt;&lt;br /&gt;Recently, I read an &lt;a rel="nofollow" target="_blank" href="http://blogs.msdn.com/shawnhar/archive/2009/06/10/pumping-the-guide.aspx"&gt;article&lt;/a&gt; by Shawn Hargreaves, "Pumping the Guide", where he describes some design issues with using the Guide on the Xbox. The Guide is the part of the Xbox GUI which is used for performing common operations, such as entering text, selecting a device where game data is saved, seeing which of your friends are online and what they are doing... The problem is to have the game still running in the background while the Guide is opened.&lt;br /&gt;&lt;br /&gt;The solution chosen by the XNA team was to make calls to the Guide non-blocking. This however makes it harder for game developers to use it, as it forces them to keep track of the application state explicitly, including both the state of the game and the state of the Guide.&lt;br /&gt;&lt;br /&gt;Kevin Gadd's shows a elegant solution to this problem in C# using custom enumerators in an &lt;a rel="nofollow" target="_blank" href="http://www.luminance.org/code/2009/06/13/asynchronous-programming-for-xna-games-with-squaredtask"&gt;article&lt;/a&gt; aptly named "Asynchronous programming for xna games with Squared.Task".&lt;br /&gt;&lt;br /&gt;Kevin's implementation in C# is as pretty as it can get, but it would probably look even better in F# using asynchronous computations. Although the async { ... } notations is exactly what we want, the Async functions do not seem to support the kind of single-threaded concurrency that Kevin's Square.Task does.&lt;br /&gt;&lt;br /&gt;The code by gneverov however should be easy to modify to execute one single step in one of the active tasks, if it does not already support that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3205414380859703216-4362022613846960696?l=sharp-gamedev.blogspot.com'/&gt;&lt;/div&gt;&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247062860"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1247062860" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/wem9poxzVlydij8EIOFdOGQ5znI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wem9poxzVlydij8EIOFdOGQ5znI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/wem9poxzVlydij8EIOFdOGQ5znI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wem9poxzVlydij8EIOFdOGQ5znI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=v248fjcBVxY:v2Q_QFMNBWY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=v248fjcBVxY:v2Q_QFMNBWY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=v248fjcBVxY:v2Q_QFMNBWY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=v248fjcBVxY:v2Q_QFMNBWY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=v248fjcBVxY:v2Q_QFMNBWY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=v248fjcBVxY:v2Q_QFMNBWY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=v248fjcBVxY:v2Q_QFMNBWY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/v248fjcBVxY" height="1" width="1"/&gt;</description>
      <link>http://sharp-gamedev.blogspot.com/2009/07/concurrency-on-single-thread.html</link>
      <author>noreply@blogger.com (Joh.)</author>
      <pubDate>Wed, 08 Jul 2009 03:21:00 GMT</pubDate>
    </item>
    <item>
      <title>Problems with fslex and fsyacc</title>
      <description>&lt;p&gt;Back in 2004, we wrote a mini Mathematica implementation in OCaml in only four days. For fun, we decided to port this OCaml program to F#. Incredibly, porting just the lexer and parser from OCaml to F# has taken longer than it took us to write the entire original OCaml code! The reason is simply that OCaml has an incredibly powerful and mature suite of compiler tools for generating lexers and parsers whereas F# does not.&lt;/p&gt;&lt;p&gt;Given that our original OCaml lexer and parser for Mathematica source code were written using &lt;span style="font-family:courier new;"&gt;ocamllex&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;ocamlyacc&lt;/span&gt;, it seemed obvious to translate the code into &lt;span style="font-family:courier new;"&gt;fslex&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;fsyacc&lt;/span&gt;. However, there are some serious problems with the F# versions of these tools:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Incomplete&lt;/strong&gt;: the regular expression implementation in fslex is incomplete, not allowing portions of a match to be named and used in the corresponding action.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Unintegrated&lt;/strong&gt;: there are no Visual Studio modes for these tools and, consequently, development is cumbersome compared to OCaml development with Emacs.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Unreliable&lt;/strong&gt;: the &lt;span style="font-family:courier new;"&gt;fslex&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;fsyacc&lt;/span&gt; tools are not officially part of the F# distribution and, although they are used in the F# compiler itself, they are buggy: reporting bogus errors where there are none.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Slow&lt;/strong&gt;: where OCaml takes 0.05s to generate and compile the lexer and parser, F# takes over 10s. That is 200× slower! Suffice to say, that seriously bogs down development.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;One potential advantage of &lt;span style="font-family:courier new;"&gt;fslex&lt;/span&gt; is that simply adding &lt;span style="font-family:courier new;"&gt;--unicode&lt;/span&gt; on the command line generates a lexer for unicode rather than ASCII text. However, we have no use for unicode and, consequently, have not tested this. In contrast, the conventional OCaml solution is to drop the byte-only &lt;span style="font-family:courier new;"&gt;ocamllex&lt;/span&gt; tool in favour of a different lexer generator such as the &lt;a rel="nofollow" target="_blank" href="http://alain.frisch.fr/soft.html#ulex"&gt;&lt;span style="font-family:courier new;"&gt;ulex&lt;/span&gt; unicode lexer-generating syntax extension&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;There is another choice for lexing and parsing in F#: the &lt;a rel="nofollow" target="_blank" href="http://www.quanttec.com/fparsec/"&gt;FParsec&lt;/a&gt; monadic parser combinator library by Stephan Tolksdorf. The current release of this library does not compile with the F# May 2009 CTP but the latest version in the development repository does. The project is split into C# and F# code in order to write some performance-critical sections in C# but this means that it is distributed as two separate DLLs. We shall investigate this option in the future...&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1779668156488517434-5423624435859722298?l=flyingfrogblog.blogspot.com'/&gt;&lt;/div&gt;&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1246944360"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1246944360" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/JAFcx6Afcc2dqfvqzeYWP7ot-MM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JAFcx6Afcc2dqfvqzeYWP7ot-MM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/JAFcx6Afcc2dqfvqzeYWP7ot-MM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JAFcx6Afcc2dqfvqzeYWP7ot-MM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=uY7L3X3x_hU:7IwsPqlXw84:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=uY7L3X3x_hU:7IwsPqlXw84:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=uY7L3X3x_hU:7IwsPqlXw84:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=uY7L3X3x_hU:7IwsPqlXw84:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=uY7L3X3x_hU:7IwsPqlXw84:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=uY7L3X3x_hU:7IwsPqlXw84:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=uY7L3X3x_hU:7IwsPqlXw84:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/uY7L3X3x_hU" height="1" width="1"/&gt;</description>
      <link>http://flyingfrogblog.blogspot.com/2009/07/problems-with-fslex-and-fsyacc.html</link>
      <author>Flying Frog Consultancy Ltd.</author>
      <pubDate>Mon, 06 Jul 2009 18:26:00 GMT</pubDate>
    </item>
    <item>
      <title>Patterns and Match Expressions in F#</title>
      <description>&lt;img src="http://mschnlnine.vo.llnwd.net/d1/ch9/8/2/1/7/7/4/PatternsAndMatchExpresssions_small_ch9.png" border="0"/&gt;&lt;p&gt;In this video, programming writer, Gordon Hogenson explains and gives examples of patterns in F# and explains the use of the match expression to control branching based on patterns in data. But first, a disclaimer Gordon wanted to make: “Regrettably, I have not been able to retrain myself yet to use the word &lt;i&gt;value&lt;/i&gt; instead of &lt;i&gt;variable&lt;/i&gt;. In F#, all values are immutable by default, so it’s not really correct to use the term variable, as I do in the video.” See Part 2 of this video: &lt;a rel="nofollow" target="_blank" href="http://channel9.msdn.com/posts/kmcgrath/Active-Patterns-F/"&gt;http://channel9.msdn.com/posts/kmcgrath/Active-Patterns-F/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;You can also learn more in the topics &lt;a rel="nofollow" target="_blank" href="http://msdn.microsoft.com/en-us/library/dd547125(VS.100).aspx"&gt;Patterns&lt;/a&gt; and &lt;a rel="nofollow" target="_blank" href="http://msdn.microsoft.com/en-us/library/dd233242(VS.100).aspx"&gt;Match Expressions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Kathleen McGrath&lt;br /&gt;
Visual Studio User Education&lt;br /&gt;
&lt;a rel="nofollow" target="_blank" href="http://blogs.msdn.com/kathleen/"&gt;http://blogs.msdn.com/kathleen/&lt;/a&gt;&lt;/p&gt;&lt;img src="http://channel9.msdn.com/477128/WebViewBug.aspx?EVT=0" height="1" width="1" alt=""/&gt;&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1246935480"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1246935480" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/KXLJHVQBpWx1kSw3J7uPN1zGcbs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/KXLJHVQBpWx1kSw3J7uPN1zGcbs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/KXLJHVQBpWx1kSw3J7uPN1zGcbs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/KXLJHVQBpWx1kSw3J7uPN1zGcbs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=4BayuZBjUZY:vBEAYlxwwD8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=4BayuZBjUZY:vBEAYlxwwD8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=4BayuZBjUZY:vBEAYlxwwD8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=4BayuZBjUZY:vBEAYlxwwD8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=4BayuZBjUZY:vBEAYlxwwD8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=4BayuZBjUZY:vBEAYlxwwD8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=4BayuZBjUZY:vBEAYlxwwD8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/4BayuZBjUZY" height="1" width="1"/&gt;</description>
      <link>http://channel9.msdn.com/posts/kmcgrath/Patterns-and-Match-Expressions-in-F/</link>
      <pubDate>Mon, 06 Jul 2009 15:58:00 GMT</pubDate>
    </item>
    <item>
      <title>Discoveries This Week 07/05/2009</title>
      <description>&lt;p&gt;If you find yourself in the Boston area tomorrow, &lt;strong&gt;Monday July 6th&lt;/strong&gt;, come see &lt;strong&gt;&lt;a rel="nofollow" target="_blank" href="http://fsug.org/"&gt;Amanda Laucher’s New England F# User’s Group talk&lt;/a&gt;&lt;/strong&gt;.&amp;#160; She is currently working on a new book for O’Reilly: F# in a Nutshell.&lt;/p&gt; &lt;p&gt;&amp;#160;&lt;/p&gt; &lt;h3&gt;Luca Bolognese’s Series on LAgent: Parts &lt;a rel="nofollow" target="_blank" href="http://blogs.msdn.com/lucabol/archive/2009/05/29/lagent-an-agent-framework-in-f-part-i-workers-and-parallelworkers.aspx"&gt;One&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href="http://blogs.msdn.com/lucabol/archive/2009/06/05/lagent-an-agent-framework-in-f-part-ii-agents-and-control-messages.aspx"&gt;Two&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href="http://blogs.msdn.com/lucabol/archive/2009/06/12/lagent-an-agent-framework-in-f-part-iii-default-error-management.aspx"&gt;Three&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href="http://blogs.msdn.com/lucabol/archive/2009/06/19/lagent-an-agent-framework-in-f-part-iv-custom-error-management.aspx"&gt;Four&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href="http://blogs.msdn.com/lucabol/archive/2009/06/26/lagent-an-agent-framework-in-f-part-v-timeout-management.aspx"&gt;Five&lt;/a&gt; and &lt;a rel="nofollow" target="_blank" href="http://blogs.msdn.com/lucabol/archive/2009/07/03/lagent-an-agent-framework-in-f-part-vi-hot-swapping-of-code-and-something-silly.aspx"&gt;Six&lt;/a&gt;&lt;/h3&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;I built myself a little agent framework based on F# MailboxProcessors. I could have used MailboxProcessors directly, but they are too flexible for my goal. Even to write a simple one of these guys, you need to use async and recursion in a specific pattern […]&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt; &lt;p&gt;Each article is a worthwhile read, containing at least one tasty morsel of F# information.&amp;#160; For example, I'm sure to use the dynamic function loading from part six sometime in the near future.&lt;/p&gt; &lt;p&gt;&amp;#160;&lt;/p&gt; &lt;h3&gt;&lt;a rel="nofollow" target="_blank" href="http://www.slideshare.net/robertfpickering/tech-days-paris-intoduction-f-and-collective-intelligence"&gt;Slides for Robert Pickering’s Tech Days Paris Talk: Introduction to F# and Collective Intelligence&lt;/a&gt;&lt;/h3&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;Hello. I’m F#. Friendly, Approachable. Built in .NET.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt; &lt;p&gt;I enjoyed the quotes from Don Syme, Eric Meijer, and Julien Laugel.&amp;#160; The collective intelligence example was also very well demonstrated.&amp;#160; Most of all, I enjoyed having a chance to see how Robert Pickering puts together a F# presentation.&amp;#160; I particularly like his style of annotating functions.&amp;#160; &lt;/p&gt; &lt;p&gt;&amp;#160;&lt;/p&gt; &lt;h3&gt;&lt;a rel="nofollow" target="_blank" href="http://channel9.msdn.com/posts/matthijs/Taking-Efficiency-One-Step-Further-FSharp/"&gt;Oliver' Strum’s Channel 9 Talk on F# – Taking Efficiency One Step Further&lt;/a&gt;&lt;/h3&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;Microsoft Research describes F# as "a scripted / functional / imperative / object-oriented programming language". Combining all those aspects in one language is certainly not an easy task, but they've done a good job of it.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt; &lt;p&gt;In this talk, Oliver covers the basics well.&amp;#160; He also does a very good job at conveying why the functional programming constructs in F# are so important.&lt;/p&gt; &lt;p&gt;&amp;#160;&lt;/p&gt; &lt;h3&gt;&lt;a rel="nofollow" target="_blank" href="http://weblogs.asp.net/podwysocki/archive/2009/06/20/f-async-running-with-continuation-scissors.aspx"&gt;Matthew Podwysocki’s F# - Async Running with Continuation Scissors&lt;/a&gt;&lt;/h3&gt; &lt;blockquote&gt; &lt;p&gt;&lt;em&gt;[…] let’s walk through a simple example of using the &lt;/em&gt;&lt;a rel="nofollow" target="_blank" href="http://apiwiki.twitter.com/Twitter-API-Documentation"&gt;&lt;em&gt;Twitter HTTP API&lt;/em&gt;&lt;/a&gt;&lt;em&gt; to get a user timeline using F# asynchronous workflows.&lt;/em&gt;&amp;#160;&lt;/p&gt; &lt;/blockquote&gt; &lt;p&gt;A fast ride through the basics of using the twitter HTTP API in F#.&amp;#160; I hadn’t previously seen an example of Async.RunWithContinuations.&amp;#160; This error handling style is quite elegant.&lt;/p&gt;
&lt;div class="shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a rel="nofollow" target="_blank" href="mailto:?body=Thought you might like this: http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/05/discoveries-this-week-07-05-2009.aspx&amp;amp;;subject=Discoveries+This+Week+07%2f05%2f2009" title="Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/05/discoveries-this-week-07-05-2009.aspx"&gt;email it!&lt;/a&gt; | &lt;a rel="nofollow" target="_blank" href="http://del.icio.us/post?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/05/discoveries-this-week-07-05-2009.aspx&amp;amp;;title=Discoveries+This+Week+07%2f05%2f2009" title="Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/05/discoveries-this-week-07-05-2009.aspx"&gt;bookmark it!&lt;/a&gt; | &lt;a rel="nofollow" target="_blank" href="http://www.digg.com/submit?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/05/discoveries-this-week-07-05-2009.aspx&amp;amp;;phase=2" title="Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/05/discoveries-this-week-07-05-2009.aspx"&gt;digg it!&lt;/a&gt; | &lt;a rel="nofollow" target="_blank" href="http://reddit.com/submit?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/05/discoveries-this-week-07-05-2009.aspx&amp;amp;title=Discoveries+This+Week+07%2f05%2f2009" title="Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/05/discoveries-this-week-07-05-2009.aspx"&gt;reddit!&lt;/a&gt; | &lt;a rel="nofollow" target="_blank" href="http://www.dotnetkicks.com/submit/?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/05/discoveries-this-week-07-05-2009.aspx&amp;amp;;title=Discoveries+This+Week+07%2f05%2f2009" title="Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/05/discoveries-this-week-07-05-2009.aspx"&gt;kick it!&lt;/a&gt; | &lt;a rel="nofollow" target="_blank" href="https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/05/discoveries-this-week-07-05-2009.aspx&amp;amp;;title=Discoveries+This+Week+07%2f05%2f2009&amp;amp;;top=1" title="Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/05/discoveries-this-week-07-05-2009.aspx"&gt;live it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.atalasoft.com/cs/aggbug.aspx?PostID=18777" width="1" height="1"&gt;&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1246842660"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1246842660" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/WvBErl4fM_UZJdOY-53OTy_3rMs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WvBErl4fM_UZJdOY-53OTy_3rMs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/WvBErl4fM_UZJdOY-53OTy_3rMs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WvBErl4fM_UZJdOY-53OTy_3rMs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=md2uV0Oj6YQ:odQrpkqDyX0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=md2uV0Oj6YQ:odQrpkqDyX0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=md2uV0Oj6YQ:odQrpkqDyX0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=md2uV0Oj6YQ:odQrpkqDyX0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=md2uV0Oj6YQ:odQrpkqDyX0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=md2uV0Oj6YQ:odQrpkqDyX0:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=md2uV0Oj6YQ:odQrpkqDyX0:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/md2uV0Oj6YQ" height="1" width="1"/&gt;</description>
      <link>http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/05/discoveries-this-week-07-05-2009.aspx</link>
      <pubDate>Sun, 05 Jul 2009 14:11:00 GMT</pubDate>
    </item>
    <item>
      <title>The twits - Yet another Twitter app</title>
      <description>&lt;p style="MARGIN:0cm 0cm 10pt;" class="MsoNormal"&gt;&lt;span style="" lang="EN-US"&gt;&lt;font size="3"&gt;Taking its name from &lt;a rel="nofollow" target="_blank" href="http://twitter.com"&gt;twitter&lt;/a&gt;, with a large nod towards &lt;a rel="nofollow" target="_blank" href="http://www.amazon.com/gp/product/014241039X?ie=UTF8&amp;amp;tag=strangelights-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=014241039X"&gt;Roald Dahl's cautionary tale&lt;/a&gt;, the twits is a twitter app that lets you visualize you network of friends on twitter. &lt;a rel="nofollow" target="_blank" href="http://strangelights.com/blog/downloads/thetwits.0.1.zip"&gt;It’s available to try here&lt;/a&gt;. Before we go any further you should know that this software is in alpha status, i.e. not for the fait hearted. Here’s an image of the results below. &lt;/font&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="MARGIN:0cm 0cm 10pt;" class="MsoNormal"&gt;&lt;span style="" lang="EN-US"&gt;&lt;font size="3"&gt; &lt;img alt="the twites"/&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="MARGIN:0cm 0cm 10pt;" class="MsoNormal"&gt;&lt;span style="" lang="EN-US"&gt;&lt;font size="3"&gt;As you can see it does a reasonable job of separating other developers I follow from people at the guardian I follow (the coloured lines &amp;amp; text are added afterwards).&lt;/font&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="MARGIN:0cm 0cm 10pt;" class="MsoNormal"&gt;&lt;span style="" lang="EN-US"&gt;&lt;font size="3"&gt;The app is designed to run local and uses &lt;a rel="nofollow" target="_blank" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=333325FD-AE52-4E35-B531-508D977D32A6&amp;amp;displaylang=en"&gt;.NET 3.5&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href="http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/release.aspx"&gt;F#&lt;/a&gt;, and &lt;a rel="nofollow" target="_blank" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=10CC340B-F857-4A14-83F5-25634C3BF043&amp;amp;displaylang=en"&gt;WPF&lt;/a&gt;, if you’re running vista or win7 it’ll probably work okay out of the box, any other else and you’ll need install .NET 3.5 etc. Caveat: if you have more than about 50 friends (people you follow) it’s unlike to be able to map them all at once, first there’s the twitter API limits, then there’s the fact the algorithm is exponentially expensive in processing time and also you just won’t be able to find them on the screen. I may consider doing a &lt;a rel="nofollow" target="_blank" href="http://silverlight.net/"&gt;Silverlight port&lt;/a&gt;, if it becomes popular, to make it more accessible. The main idea of the app is to show off some of Collective Intelligence work, this app is another example of hierarchical clustering and also uses optimization. There’s also some interesting use of async workflows. If you want to try &lt;a rel="nofollow" target="_blank" href="http://github.com/robertpi/fscollintelli/tree/master"&gt;the source it’s available on git hub&lt;/a&gt;. I've lots of ideas for future version - but not much time to develop them. Licence is GPL 2.0, if you'd like that to change, lobby me. If you like it let me know!&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0cm 0cm 10pt;" class="MsoNormal"&gt;&lt;span style="" lang="EN-US"&gt;&lt;font size="3"&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; The download was broken because of a missing dll, this is fixed now. Thanks to &lt;font face=""&gt;&lt;a rel="nofollow" target="_blank" href="http://twitter.com/samjiman"&gt;@samjiman&lt;/a&gt; for noticing.&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://strangelights.com/blog/aggbug/1645.aspx" width="1" height="1"/&gt;&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1246710395"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1246710395" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/GFfeBssu0Lvt4aqJ8ywoeuho8-s/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GFfeBssu0Lvt4aqJ8ywoeuho8-s/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/GFfeBssu0Lvt4aqJ8ywoeuho8-s/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GFfeBssu0Lvt4aqJ8ywoeuho8-s/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=OZKNtzVs9b4:n6ygFulZl30:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=OZKNtzVs9b4:n6ygFulZl30:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=OZKNtzVs9b4:n6ygFulZl30:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=OZKNtzVs9b4:n6ygFulZl30:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=OZKNtzVs9b4:n6ygFulZl30:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=OZKNtzVs9b4:n6ygFulZl30:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=OZKNtzVs9b4:n6ygFulZl30:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/OZKNtzVs9b4" height="1" width="1"/&gt;</description>
      <link>http://strangelights.com/blog/archive/2009/07/04/1645.aspx</link>
      <category>F# updates</category>
      <pubDate>Sat, 04 Jul 2009 01:26:35 GMT</pubDate>
    </item>
    <item>
      <title>LAgent: an agent framework in F# – Part VI – Hot swapping of code (and something silly)</title>
      <description>&lt;h4&gt;Hot swapping of code&lt;/h4&gt; &lt;p&gt;Let’s get back a couple of steps and consider what happens when you get an error. Sure, your agent will continue processing messages, but it might be doing the wrong thing. Your message handling code might be buggy.&lt;/p&gt; &lt;p&gt;Ideally you’d want to patch things on the fly. You’d want to replace the message processing code for an agent without stopping it.&lt;/p&gt; &lt;p&gt;Here is how you do it:&lt;/p&gt; &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;let &lt;/span&gt;counter2 = spawnAgent (&lt;span style="color:blue;"&gt;fun &lt;/span&gt;msg state &lt;span style="color:blue;"&gt;-&amp;gt; &lt;/span&gt;printfn &lt;span style="color:maroon;"&gt;"From %i to %i" &lt;/span&gt;state (state + msg);&lt;br /&gt; state + msg) 0
counter2 &amp;lt;-- 2 counter2 &amp;lt;-- SetAgentHandler(&lt;span style="color:blue;"&gt;fun &lt;/span&gt;msg state –&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt; &lt;/span&gt;printfn &lt;span style="color:maroon;"&gt;"From %i to %i via multiplication" &lt;/span&gt;state (state * msg); msg * state)
counter2 &amp;lt;-- 3&lt;/pre&gt;
&lt;a rel="nofollow" target="_blank" href="http://11011.net/software/vspaste"&gt;&lt;/a&gt; &lt;p&gt;Which generates:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;strong&gt;From 0 to 2 &lt;br /&gt;From 2 to 6 via multiplication&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt; &lt;p&gt;After the agent receives a &lt;em&gt;SetAgentHandler&lt;/em&gt; message, it switch from a ‘+’ agent to a ‘*’ agent on the fly!! All the messages that come after that one gets multiplied to the state. Also, the state is preserved between changes in behavior.&lt;/p&gt; &lt;p&gt;It might not be immediately apparent how to load a function at runtime, but it is really simple. Imagine that I get the data on the function to load from somewhere (i.e. a management console UI).&lt;/p&gt; &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;let &lt;/span&gt;assemblyNameFromSomewhere, typeNameFromSomewhere, methodNameFromSomewhere = &lt;br /&gt; &lt;span style="color:maroon;"&gt;"mscorlib.dll"&lt;/span&gt;, &lt;span style="color:maroon;"&gt;"System.Console"&lt;/span&gt;, &lt;span style="color:maroon;"&gt;"WriteLine"&lt;/span&gt;&lt;/pre&gt; &lt;p&gt;I can then use it to dynamically load a message handler (in this case &lt;em&gt;Console.Writeline&lt;/em&gt;).&lt;/p&gt; &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;let &lt;/span&gt;a = Assembly.Load(assemblyNameFromSomewhere)
&lt;span style="color:blue;"&gt;let &lt;/span&gt;c = a.GetType(typeNameFromSomewhere)
&lt;span style="color:blue;"&gt;let &lt;/span&gt;m = c.GetMethod(methodNameFromSomewhere, [|&lt;span style="color:maroon;"&gt;""&lt;/span&gt;.GetType()|])
&lt;span style="color:blue;"&gt;let &lt;/span&gt;newF = &lt;span style="color:blue;"&gt;fun &lt;/span&gt;(msg:string) (state:obj) &lt;span style="color:blue;"&gt;-&amp;gt; &lt;/span&gt;m.Invoke(&lt;span style="color:blue;"&gt;null&lt;/span&gt;, [| (msg:&amp;gt;obj) |])&lt;/pre&gt; &lt;p&gt;And then it is as simple as posting a &lt;em&gt;SetAgentHandler&lt;/em&gt;.&lt;/p&gt; &lt;pre class="code"&gt;counter2 &amp;lt;-- SetAgentHandler(newF)
counter2 &amp;lt;-- &lt;span style="color:maroon;"&gt;"blah"&lt;/span&gt;&lt;/pre&gt; &lt;p&gt;Now our &lt;em&gt;counter2&lt;/em&gt; agent has become an echo agent on the fly, having loaded &lt;em&gt;Console.WriteLine&lt;/em&gt; dynamically. Note how the agent moved from being a ‘+’ agent taking integers to being a ‘*’ agent taking integers to being an ‘echo’ agent taking strings. And it didn’t stop processing messages for the whole time.&lt;/p&gt; &lt;p&gt;Obviously, you can do the same thing with workers:&lt;/p&gt; &lt;pre class="code"&gt;echo &amp;lt;-- SetWorkerHandler(&lt;span style="color:blue;"&gt;fun &lt;/span&gt;msg &lt;span style="color:blue;"&gt;-&amp;gt; &lt;/span&gt;printfn &lt;span style="color:maroon;"&gt;"I'm an echo and I say: %s" &lt;/span&gt;msg)
echo &amp;lt;-- &lt;span style="color:maroon;"&gt;"Hello"&lt;/span&gt;&lt;/pre&gt; &lt;p&gt;And parallelWorkers:&lt;/p&gt; &lt;pre class="code"&gt;parallelEcho &amp;lt;-- SetWorkerHandler(&lt;span style="color:blue;"&gt;fun &lt;/span&gt;msg &lt;span style="color:blue;"&gt;-&amp;gt; &lt;/span&gt;tprint (&lt;span style="color:maroon;"&gt;"I'm new and " &lt;/span&gt;+ msg))
messages |&amp;gt; Seq.iter (&lt;span style="color:blue;"&gt;fun &lt;/span&gt;msg &lt;span style="color:blue;"&gt;-&amp;gt; &lt;/span&gt;parallelEcho &amp;lt;-- msg)&lt;/pre&gt; &lt;h4&gt;A silly interlude&lt;/h4&gt; &lt;p&gt;As a way to show some agents talking to each other, here is a simple program that simulates marital interactions (of the worst kind):&lt;/p&gt; &lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;let rec &lt;/span&gt;husband = spawnWorker (&lt;span style="color:blue;"&gt;fun &lt;/span&gt;(To, msg) &lt;span style="color:blue;"&gt;-&amp;gt; &lt;/span&gt;printfn &lt;span style="color:maroon;"&gt;"Husband says: %s" &lt;/span&gt;msg; To &amp;lt;-- msg)
&lt;span style="color:blue;"&gt;let rec &lt;/span&gt;wife = spawnWorker (&lt;span style="color:blue;"&gt;fun &lt;/span&gt;msg &lt;span style="color:blue;"&gt;-&amp;gt; &lt;/span&gt;printfn &lt;span style="color:maroon;"&gt;"Wife says: screw you and your '%s'" &lt;/span&gt;msg)
husband &amp;lt;-- (wife, &lt;span style="color:maroon;"&gt;"Hello"&lt;/span&gt;)
husband &amp;lt;-- (wife, &lt;span style="color:maroon;"&gt;"But darling ..."&lt;/span&gt;)
husband &amp;lt;-- (wife, &lt;span style="color:maroon;"&gt;"ok"&lt;/span&gt;)&lt;/pre&gt; &lt;p&gt;Which produces:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;strong&gt;Husband says: Hello &lt;br /&gt;Husband says: But darling ... &lt;br /&gt;Wife says: screw you and your 'Hello' &lt;br /&gt;Wife says: screw you and your 'But darling ...' &lt;br /&gt;Husband says: ok &lt;br /&gt;Wife says: screw you and your 'ok'&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt; &lt;p&gt;And yes, you cannot expect messages to be in the right sequence … Next up is an auction application.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9649341" width="1" height="1"&gt;&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1246659780"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1246659780" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ltVehLA_ze2RAnKNkROel8EbGE0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ltVehLA_ze2RAnKNkROel8EbGE0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ltVehLA_ze2RAnKNkROel8EbGE0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ltVehLA_ze2RAnKNkROel8EbGE0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=S5oY32-iTOU:VmfM7zX4Jnw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=S5oY32-iTOU:VmfM7zX4Jnw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=S5oY32-iTOU:VmfM7zX4Jnw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=S5oY32-iTOU:VmfM7zX4Jnw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=S5oY32-iTOU:VmfM7zX4Jnw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=S5oY32-iTOU:VmfM7zX4Jnw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=S5oY32-iTOU:VmfM7zX4Jnw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/S5oY32-iTOU" height="1" width="1"/&gt;</description>
      <link>http://blogs.msdn.com/lucabol/archive/2009/07/03/lagent-an-agent-framework-in-f-part-vi-hot-swapping-of-code-and-something-silly.aspx</link>
      <pubDate>Fri, 03 Jul 2009 11:23:00 GMT</pubDate>
    </item>
    <item>
      <title>WiX again.</title>
      <description>In my previous post I expressed my disappointment with WiX. However, after an additional day of struggling with it, I may change my mind. I managed to find a pretty straightforward solution to (almost) all my problems. Getting there wasn't straightforward at all, though.&lt;br /&gt;&lt;br /&gt;Here are the lessons I learned in the process:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Do not overwrite existing files using &amp;lt;File&amp;gt; elements.&lt;/span&gt;&lt;br /&gt;When your software gets uninstalled, it will remove your file, but the old file won't be restored. The solution that first popped up in my mind, namely to backup old files, isn't as easy as it seems. The problem is that the backup copy will be left behind after the software gets uninstalled.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&amp;lt;CopyFile&amp;gt; is not your friend.&lt;/span&gt;&lt;br /&gt;...at least as far as backing up existing files goes. I tried to back up the old file by copying it into my application's folder using CopyFile, and failed miserably. Maybe I missed something, but it seems CopyFile is designed to make copies of the files you install, not of existing files.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&amp;lt;CustomAction&amp;gt; is way too complex for its own good (and yours).&lt;/span&gt;&lt;br /&gt;CustomAction can be used in many different ways, using slightly different syntaxes. I attempted to use it to backup files, and finally succeeded. It wasn't easy. I tried to use it to run a command (COPY), but it failed. Same problem with other commands such as REN and DEL. No success running batch files either. I tried running a jscript, and that failed too. Since the creator pf WiX advises against using scripts in custom actions, I did not insist. I ended up using "xcopy.exe", which worked (with a catch: the target must be an existing directory, otherwise xcopy demands to interact with the user, and we don't want that).&lt;br /&gt;&lt;br /&gt;I found ONE use of CustomAction, and I am not planning on trying out other uses. At least not for a while.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&amp;lt;RemoveFile&amp;gt; is your friend.&lt;/span&gt;&lt;br /&gt;Unlike CopyFile, it's easy to use to clear up stuff in your application's folder. I used it to remove the backup after restoring it during uninstallation.&lt;br /&gt;&lt;br /&gt;In case you wonder how to handle back-ups in WiX, that's the way I did it:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;&lt;br /&gt;&amp;lt;Property Id='XCOPY'&amp;gt;xcopy.exe&amp;lt;/Property&amp;gt;&lt;br /&gt;...&lt;br /&gt;&amp;lt;CustomAction Id='Backup'&lt;br /&gt; Property='XCOPY'&lt;br /&gt; ExeCommand='"[ExistingFolder]PlugIn.dll" "[OldFiles]" /Y'&lt;br /&gt; Result='check'&lt;br /&gt; Execute='deferred' /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;CustomAction Id='Install'&lt;br /&gt; Property='XCOPY'&lt;br /&gt; ExeCommand='"[NewFiles]PlugIn.dll" "[ExistingFolder]" /Y'&lt;br /&gt; Result='check'&lt;br /&gt; Execute='deferred' /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;CustomAction Id='Restore'&lt;br /&gt; Property='XCOPY'&lt;br /&gt; ExeCommand='"[OldFiles]PlugIn.dll" "[ExistingFolder]" /Y'&lt;br /&gt; Result='ignore'&lt;br /&gt; Execute='deferred' /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;InstallExecuteSequence&amp;gt;&lt;br /&gt; &amp;lt;Custom Action='BackupPlugIn' Before='InstallPlugIn'&amp;gt;Not Installed&amp;lt;/Custom&amp;gt;&lt;br /&gt; &amp;lt;Custom Action='InstallPlugIn' After='InstallFiles'&amp;gt;Not Installed&amp;lt;/Custom&amp;gt;&lt;br /&gt; &amp;lt;Custom Action='RestorePlugIn' Before='RemoveFiles'&amp;gt;Installed&amp;lt;/Custom&amp;gt;&lt;br /&gt;&amp;lt;/InstallExecuteSequence&amp;gt;&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&amp;lt;Directory Id='NewFiles' Name='New Files'&amp;gt;&lt;br /&gt; &amp;lt;Component Id='NewFiles' Guid='...'&amp;gt;&lt;br /&gt; &amp;lt;File Id='NewFile' Name='Plugin.dll' Source='build/PlugIn.dll' /&amp;gt;&lt;br /&gt; &amp;lt;/Component&amp;gt;&lt;br /&gt;&amp;lt;/Directory&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;Directory Id='OldFiles' Name='Old Files'&amp;gt;&lt;br /&gt; &amp;lt;Component Id='OldFiles' Guid='...'&amp;gt;&lt;br /&gt; &amp;lt;CreateFolder /&amp;gt;&lt;br /&gt; &amp;lt;RemoveFile Id='CleanUpBackup' Name='PlugIn.dll' On='uninstall' /&amp;gt;&lt;br /&gt; &amp;lt;/Component&amp;gt;&lt;br /&gt;&amp;lt;/Directory&amp;gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Note how I avoided overwriting files in the "Component" elements. I do that using CustomAction instead, both when installing my plug-in and when restoring the old one.&lt;br /&gt;&lt;br /&gt;Something that's missing are rollback actions. There should be one for each deferred action, namely an action removing the xcopy-ed file. I don't know of any standard program to remove files on Windows, and I'd rather not write one myself. Where is "rm"?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;UPDATE:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;WiX experts are probably shaking their heads when they read this code:&lt;br /&gt;&lt;br /&gt;&lt;div class="mycode"&gt;&lt;br /&gt; &amp;lt;Custom Action='RestorePlugIn' Before='RemoveFiles'&amp;gt;Installed&amp;lt;/Custom&amp;gt;&lt;br /&gt;&amp;lt;/InstallExecuteSequence&amp;gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;While it does do what I intended when the user removes the software, it is also executed when users perform other actions than install or uninstall, such as repair an installation. As a result, an attempt to repair an installation will restore the old plug-in, which of course is more likely to destroy the installed software...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3205414380859703216-2929525480437294778?l=sharp-gamedev.blogspot.com'/&gt;&lt;/div&gt;&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1246555440"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1246555440" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/h-O_rXfM2YzsxmjL4RbWuZGYxsg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/h-O_rXfM2YzsxmjL4RbWuZGYxsg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/h-O_rXfM2YzsxmjL4RbWuZGYxsg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/h-O_rXfM2YzsxmjL4RbWuZGYxsg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=qfr5Pq44AhA:pK6wwuUNpJM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=qfr5Pq44AhA:pK6wwuUNpJM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=qfr5Pq44AhA:pK6wwuUNpJM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=qfr5Pq44AhA:pK6wwuUNpJM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=qfr5Pq44AhA:pK6wwuUNpJM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=qfr5Pq44AhA:pK6wwuUNpJM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=qfr5Pq44AhA:pK6wwuUNpJM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/qfr5Pq44AhA" height="1" width="1"/&gt;</description>
      <link>http://sharp-gamedev.blogspot.com/2009/07/wix-again.html</link>
      <author>noreply@blogger.com (Joh.)</author>
      <pubDate>Thu, 02 Jul 2009 06:24:00 GMT</pubDate>
    </item>
    <item>
      <title>F# BootCamp – Questions and Answers – part IV – Structural comparison</title>
      <description>&lt;p&gt;This is the third part in a “Questions and Answers”-series about the &lt;a rel="nofollow" target="_blank" href="http://dotnet-leipzig.de/veranstaltungen/net-bootcamp-2009-5/"&gt;F# BootCamp in Leipzig&lt;/a&gt;. This time we will look at structural comparison and structural equality.&lt;/p&gt;
&lt;h5&gt;Question 6: Please describe the terms “Structural Comparison” and “Structural Equality”.&lt;/h5&gt;
&lt;p&gt;This was a simple question. Basically the answer is F# provides a default implementation for IComparable and .Equals() for all custom types. This default implementation compares all public fields of the two instances. Let’s consider some samples:&lt;/p&gt;
&lt;h5&gt;Tuples&lt;/h5&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;let &lt;/span&gt;a = 3,4,&lt;span style="color:maroon;"&gt;"foo"
&lt;/span&gt;&lt;span style="color:blue;"&gt;let &lt;/span&gt;b = 3,4,&lt;span style="color:maroon;"&gt;"bar" &lt;/span&gt;printfn &lt;span style="color:maroon;"&gt;"a &amp;gt; b = %b" &lt;/span&gt;(a &amp;gt; b) &lt;span style="color:green;"&gt;// true
&lt;/span&gt;printfn &lt;span style="color:maroon;"&gt;"a &amp;lt; b = %b" &lt;/span&gt;(a &amp;lt; b) &lt;span style="color:green;"&gt;// false&lt;/span&gt;&lt;/pre&gt;
&lt;h5&gt;Records&lt;/h5&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;type &lt;/span&gt;MySimpleRecord = { a: int; b: int;} &lt;span style="color:blue;"&gt;type &lt;/span&gt;MyCompositeRecord = { x: string; y: int; z: MySimpleRecord} &lt;span style="color:blue;"&gt;let &lt;/span&gt;a = { x = &lt;span style="color:maroon;"&gt;"Test"&lt;/span&gt;; y = 3; z = {a = 1; b = 4;}} &lt;span style="color:blue;"&gt;let &lt;/span&gt;b = { x = &lt;span style="color:maroon;"&gt;"Test"&lt;/span&gt;; y = 3; z = {a = 1; b = 2;}} &lt;span style="color:green;"&gt;// Structural comparison
&lt;/span&gt;printfn &lt;span style="color:maroon;"&gt;"a &amp;gt; b = %b" &lt;/span&gt;(a &amp;gt; b) &lt;span style="color:green;"&gt;// true
&lt;/span&gt;printfn &lt;span style="color:maroon;"&gt;"a &amp;lt; b = %b" &lt;/span&gt;(a &amp;lt; b) &lt;span style="color:green;"&gt;// false&lt;/span&gt; printfn &lt;span style="color:maroon;"&gt;"Min(a,b) = %A" &lt;/span&gt;(min a b)
printfn &lt;span style="color:maroon;"&gt;"compare(a,b) = %d" &lt;/span&gt;(compare a b) &lt;/pre&gt;
&lt;h5&gt;Lists&lt;/h5&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;let &lt;/span&gt;a = [3; 2; 4; 5]
&lt;span style="color:blue;"&gt;let &lt;/span&gt;b = [3; 2; 4; 3; 3] &lt;span style="color:green;"&gt;// Structural comparison
&lt;/span&gt;printfn &lt;span style="color:maroon;"&gt;"a &amp;gt; b = %b" &lt;/span&gt;(a &amp;gt; b) &lt;span style="color:green;"&gt;// true
&lt;/span&gt;printfn &lt;span style="color:maroon;"&gt;"a &amp;lt; b = %b" &lt;/span&gt;(a &amp;lt; b) &lt;span style="color:green;"&gt;// false &lt;/span&gt;printfn &lt;span style="color:maroon;"&gt;"Min(a,b) = %A" &lt;/span&gt;(min a b)
printfn &lt;span style="color:maroon;"&gt;"compare(a,b) = %d" &lt;/span&gt;(compare a b)&lt;/pre&gt;
&lt;p&gt;&amp;copy;2009 &lt;a rel="nofollow" target="_blank" href="http://www.navision-blog.de"&gt;Rash thoughts about .NET, C#, F# and Dynamics NAV.&lt;/a&gt;. All Rights Reserved.&lt;/p&gt;.&lt;p&gt;&lt;a rel="nofollow" target="_blank" href="http://www.pheedo.com/click.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1246549030"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=60c11b8469e54dfba87cebc201b448d0&amp;u=planetfsharp1246549030" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ZyGAIO7_S0iervDoCUTOAH39Ghg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZyGAIO7_S0iervDoCUTOAH39Ghg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ZyGAIO7_S0iervDoCUTOAH39Ghg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZyGAIO7_S0iervDoCUTOAH39Ghg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=OSQuRzHhwZI:T0ehFQ6ev3c:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=OSQuRzHhwZI:T0ehFQ6ev3c:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=OSQuRzHhwZI:T0ehFQ6ev3c:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=OSQuRzHhwZI:T0ehFQ6ev3c:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=OSQuRzHhwZI:T0ehFQ6ev3c:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/planet_fsharp?a=OSQuRzHhwZI:T0ehFQ6ev3c:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/planet_fsharp?i=OSQuRzHhwZI:T0ehFQ6ev3c:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/planet_fsharp/~4/OSQuRzHhwZI" height="1" width="1"/&gt;</description>
      <link>http://www.navision-blog.de/2009/07/02/f-bootcamp-questions-and-answers-part-iv-structural-comparison/</link>
      <pubDate>Thu, 02 Jul 2009 04:37:10 GMT</pubDate>
    </item>
  </channel>
</rss>
