<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.technet.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>The Applied Games Group Blog : Development</title><link>http://blogs.technet.com/apg/archive/tags/Development/default.aspx</link><description>Tags: Development</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>TrueSkill in F#</title><link>http://blogs.technet.com/apg/archive/2008/06/16/trueskill-in-f.aspx</link><pubDate>Mon, 16 Jun 2008 07:25:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3071681</guid><dc:creator>apg</dc:creator><slash:comments>37</slash:comments><comments>http://blogs.technet.com/apg/comments/3071681.aspx</comments><wfw:commentRss>http://blogs.technet.com/apg/commentrss.aspx?PostID=3071681</wfw:commentRss><description>&lt;P&gt;Following the &lt;A href="http://blogs.technet.com/apg/archive/2008/04/05/trueskill-through-time.aspx" mce_href="http://blogs.technet.com/apg/archive/2008/04/05/trueskill-through-time.aspx"&gt;publication&lt;/A&gt; of the &lt;A href="http://research.microsoft.com/fsharp/fsharp.aspx" mce_href="http://research.microsoft.com/fsharp/fsharp.aspx"&gt;F#&lt;/A&gt; source code for the &lt;A href="http://research.microsoft.com/osa/apg/trueskill.aspx" mce_href="http://research.microsoft.com/osa/apg/trueskill.aspx"&gt;TrueSkill&lt;/A&gt; Through Time paper, we have used the same inference library code to demonstrate how the original TrueSkill algorithm can be coded. In the attached source code, only the &lt;U&gt;program.fs&lt;/U&gt; file is different to the TrueSkill through Time blog post and it builds up the factor graph for an arbitrary N-player game with an arbitrary draw probability. Both these numbers can be entered on the command line when running the resulting sample. We tried to make sure to stay as close as possible to the description on page 3 of the &lt;A href="ftp://ftp.research.microsoft.com/pub/tr/TR-2006-80.pdf" mce_href="ftp://ftp.research.microsoft.com/pub/tr/TR-2006-80.pdf"&gt;TrueSkill technical report&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;The attached ZIP file contains the entire source code which should compile without problems with &lt;A href="http://research.microsoft.com/research/downloads/Details/7ac148a7-149b-4056-aa06-1e6754efd36f/Details.aspx"&gt;F# 1.9.3.14&lt;/A&gt;. You can either load the solution in Visual Studio 2008 or simply run build.bat form the command line - in either case you will end up with a &lt;U&gt;trueskill.exe&lt;/U&gt; program. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Update&lt;/STRONG&gt;: Following the release of the &lt;A href="http://msdn.microsoft.com/en-us/fsharp/default.aspx" mce_href="http://msdn.microsoft.com/en-us/fsharp/default.aspx"&gt;F# September 2008 CTP&lt;/A&gt; we have updated the source code to work with &lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=61ad6924-93ad-48dc-8c67-60f7e7803d3c&amp;amp;displaylang=en" mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyID=61ad6924-93ad-48dc-8c67-60f7e7803d3c&amp;amp;displaylang=en"&gt;F# 1.9.6.2&lt;/A&gt;. Also, we added one of the new features of F#, namely units-of-measure, which makes the TrueSkill update invocation calls now read as follows:&lt;/P&gt;
&lt;P style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: windowtext; mso-no-proof: yes; mso-bidi-font-size: 10.0pt"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; mso-no-proof: yes; mso-bidi-font-size: 10.0pt"&gt;let&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: windowtext; mso-no-proof: yes; mso-bidi-font-size: 10.0pt"&gt; priorMu = 25.0&amp;lt;SkillPoints&amp;gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: windowtext; mso-no-proof: yes; mso-bidi-font-size: 10.0pt"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; mso-no-proof: yes; mso-bidi-font-size: 10.0pt"&gt;let&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: windowtext; mso-no-proof: yes; mso-bidi-font-size: 10.0pt"&gt; priorSigma = priorMu / 3.0&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: windowtext; mso-no-proof: yes; mso-bidi-font-size: 10.0pt"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; mso-no-proof: yes; mso-bidi-font-size: 10.0pt"&gt;let&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: windowtext; mso-no-proof: yes; mso-bidi-font-size: 10.0pt"&gt; priorSkills = Array.init noPlayers (&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; mso-no-proof: yes; mso-bidi-font-size: 10.0pt"&gt;fun&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: windowtext; mso-no-proof: yes; mso-bidi-font-size: 10.0pt"&gt; i &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; mso-no-proof: yes; mso-bidi-font-size: 10.0pt"&gt;-&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: windowtext; mso-no-proof: yes; mso-bidi-font-size: 10.0pt"&gt; Gaussian.Create (priorMu, priorSigma))&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: windowtext; mso-no-proof: yes; mso-bidi-font-size: 10.0pt"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: blue; mso-no-proof: yes; mso-bidi-font-size: 10.0pt"&gt;let&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: windowtext; mso-no-proof: yes; mso-bidi-font-size: 10.0pt"&gt; (posteriorSkills, logZ) = &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none" class=MsoNormal&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; COLOR: windowtext; mso-no-proof: yes; mso-bidi-font-size: 10.0pt"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;NPlayerTrueSkillUpdate (0.5*priorSigma, 0.01*priorSigma, drawProb / 100.0) priorSkills&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Note that one can no longer accidentally pass the variance instead of the standard deviation because the former being of type &lt;FONT face="Courier New"&gt;float&amp;lt;SkillPoints^2&amp;gt;&lt;FONT face=Arial&gt;. Try yourself!&lt;/FONT&gt; &lt;/FONT&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;Update 2&lt;/STRONG&gt;: We had some feedback from Andrew Kennedy that we exploited a current "bug" in the units-of-measure code where literals (such as 1.0) can have generic units. We removed the incorrect usages and re-posted the ZIP file.&amp;nbsp;&lt;/P&gt;&lt;STRONG&gt;Update 3&lt;/STRONG&gt;: We extended the example to work with draws. Thanks to Chih-Jen Lin for the suggestion!&amp;nbsp; 
&lt;P mce_keep="true"&gt;&lt;FONT face="Courier New"&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;
&lt;P mce_keep="true"&gt;&lt;SMALL&gt;Ralf Herbrich &amp;amp; Thore Graepel&lt;/SMALL&gt;&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3071681" width="1" height="1"&gt;</description><enclosure url="http://blogs.technet.com/apg/attachment/3071681.ashx" length="9696" type="application/x-zip-compressed" /><category domain="http://blogs.technet.com/apg/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.technet.com/apg/archive/tags/Bayesian/default.aspx">Bayesian</category><category domain="http://blogs.technet.com/apg/archive/tags/Machine+Learning/default.aspx">Machine Learning</category><category domain="http://blogs.technet.com/apg/archive/tags/TrueSkill/default.aspx">TrueSkill</category><category domain="http://blogs.technet.com/apg/archive/tags/Development/default.aspx">Development</category></item><item><title>Statically link with ILMerge</title><link>http://blogs.technet.com/apg/archive/2008/05/29/statically-link-with-ilmerge.aspx</link><pubDate>Thu, 29 May 2008 21:49:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3062869</guid><dc:creator>apg</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.technet.com/apg/comments/3062869.aspx</comments><wfw:commentRss>http://blogs.technet.com/apg/commentrss.aspx?PostID=3062869</wfw:commentRss><description>&lt;P&gt;Today Ralf &amp;amp; I were looking at ways to bundle up a&amp;nbsp;bunch of .Net assemblies into a single assembly for use within&amp;nbsp;our group; the goal to&amp;nbsp;expose only the functionality we want and only need to reference&amp;nbsp;one assembly in our projects. Enter command line app &lt;A class="" href="http://research.microsoft.com/~mbarnett/ILMerge.aspx" mce_href="http://research.microsoft.com/~mbarnett/ILMerge.aspx"&gt;ILMerge&lt;/A&gt; by Michael Barnett of Microsoft Research which lets you merge a set of dlls into a single assembly and selectively hide functionality by changing &lt;A class="" href="http://msdn.microsoft.com/en-us/library/yzh058ae(VS.71).aspx" mce_href="http://msdn.microsoft.com/en-us/library/yzh058ae(VS.71).aspx"&gt;public access modifiers&lt;/A&gt; to &lt;A class="" href="http://msdn.microsoft.com/en-us/library/7c5ka91b(VS.71).aspx" mce_href="http://msdn.microsoft.com/en-us/library/7c5ka91b(VS.71).aspx"&gt;internal&lt;/A&gt;.&amp;nbsp;The first&amp;nbsp;assembly&amp;nbsp;you specify on the command line&amp;nbsp;is the primary one and it's types maintain their access modifiers, the subsequent assembles are the ones that can be hidden by using ILMerge's ExcludeFile parameter where you can specify a file which in turn&amp;nbsp;contains a list of &lt;A class="" href="http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.aspx"&gt;regular expressions&lt;/A&gt;&amp;nbsp;for the&amp;nbsp;types&amp;nbsp;you would like to&amp;nbsp;keep public. When you merge the assemblies if you have&amp;nbsp;also written XML code documentation files these get merged too, so you even get to keep the &lt;A class="" href="http://en.wikipedia.org/wiki/IntelliSense" mce_href="http://en.wikipedia.org/wiki/IntelliSense"&gt;intellisense&lt;/A&gt; tooltips on the classes and functions you have documented with /// comments.&amp;nbsp;For C#&amp;nbsp;projects you can specify XML documentation output&amp;nbsp;in the project's Visual Studio build properties, and for &lt;A class="" href="http://en.wikipedia.org/wiki/F%E2%99%AF_%28programming_language%29" mce_href="http://en.wikipedia.org/wiki/F%E2%99%AF_%28programming_language%29"&gt;F#&lt;/A&gt;&amp;nbsp;projects you can use the command line &lt;EM&gt;-doc filename&lt;/EM&gt; option. To quickly check if we were getting the desired results in our target assembly we used the&amp;nbsp;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/f7dy01k1(VS.80).aspx" mce_href="http://msdn.microsoft.com/en-us/library/f7dy01k1(VS.80).aspx"&gt;ILdasm&lt;/A&gt;&amp;nbsp;tool to walk through our types. While&amp;nbsp;checking the output&amp;nbsp;we noticed that by default in the current F#, triple slash XML comments&amp;nbsp;get embedded in the assembly for use in Visual Studio for tooltips; but if you are already generating seperate XML documentation it is possible to turn off this feature with the &lt;A class="" href="http://blogs.technet.com/controlpanel/blogs/--no-interface-data" mce_href="http://blogs.technet.com/controlpanel/blogs/--no-interface-data "&gt;&lt;EM&gt;--no-interface-data&lt;/EM&gt;&lt;/A&gt; command line option. So in summary ILMerge&amp;nbsp;appears to be&amp;nbsp;a great, highly customisable tool that lets you&amp;nbsp;distribute a single assembly exposing just the functionality you want to expose (just like linking good old&amp;nbsp;.Lib files in C++ :)).&lt;/P&gt;
&lt;P&gt;Phil&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3062869" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/apg/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.technet.com/apg/archive/tags/Development/default.aspx">Development</category></item><item><title>BabyJack Inline Video Card Game</title><link>http://blogs.technet.com/apg/archive/2008/05/26/Babyjack-Inline-Video-Blackjack.aspx</link><pubDate>Mon, 26 May 2008 13:27:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3061129</guid><dc:creator>apg</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.technet.com/apg/comments/3061129.aspx</comments><wfw:commentRss>http://blogs.technet.com/apg/commentrss.aspx?PostID=3061129</wfw:commentRss><description>&lt;P mce_keep="true"&gt;Its been yet another wet&amp;nbsp;and windy bank&amp;nbsp;holiday weekend here in the UK,&amp;nbsp;so&amp;nbsp;I decided&amp;nbsp;to involve the family and create&amp;nbsp;a video &lt;A class="" href="http://en.wikipedia.org/wiki/Blackjack" mce_href="http://en.wikipedia.org/wiki/Blackjack"&gt;Blackjack&lt;/A&gt; called BabyJack,&amp;nbsp;despite the baby's name being Sean&amp;nbsp;not Jack :). Just press the Play button below to pit your wits against the baby...&lt;/P&gt;
&lt;TABLE class="" border=8&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=""&gt;
&lt;DIV id=wmp&gt;&lt;/DIV&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" align=middle&gt;
&lt;DIV id=Prompt style="FONT-SIZE: 20px; FONT-FAMILY: fantasy"&gt;&lt;INPUT style="FONT-SIZE: 20px; FONT-FAMILY: fantasy" onclick=Javascript:Shuffle(); type=button value="Play BabyJack!"&gt;&lt;/INPUT&gt; &lt;/DIV&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;SCRIPT type=text/javascript&gt;
if(-1 != navigator.userAgent.indexOf("MSIE"))
{
	var element = document.getElementById("wmp");
	element.innerHTML = "&lt;OBJECT id=player height=280 width=340 type =application/x-oleobject classid=CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6 &gt;&lt;PARAM NAME=\"URL\" VALUE=\"http://www.trelford.com/BabyJack.gif\"&gt;&lt;PARAM NAME=\"uiMode\" VALUE=\"none\"&gt;&lt;/OBJECT&gt;";
}
else
{
	var element = document.getElementById("wmp");
	element.innerHTML = "&lt;OBJECT id=player height=280 width=340 type=application/x-ms-wmp &gt;&lt;PARAM NAME=\"URL\" VALUE=\"http://www.trelford.com/BabyJack.gif\"&gt;&lt;PARAM NAME=\"uiMode\" VALUE=\"none\"&gt;&lt;/OBJECT&gt;";
}


var player = theForm.player;

function Pair(first,second)
{
	this.fst = first;
	this.snd = second;
	this.toString = function () { return "("+this.fst+","+this.snd+")"; }
}

function Card(rank, suit) {

	function HighValue(rank)
	{
		switch (rank)
		{
			case '2': return 2;
			case '3': return 3;
			case '4': return 4;
			case '5': return 5;
			case '6': return 6;
			case '7': return 7;
			case '8': return 8;
			case '9': return 9;
			case 'J': return 10;
			case 'Q': return 10;
			case 'K': return 10;
			case 'A': return 11;		
		}
		return 0;
	}

	function LowValue (rank)
	{
		if (rank == 'A') return 1;
		return HighValue (rank);
	}

	this.rank = rank;
	this.suit = suit;
	this.highValue = HighValue(rank);
	this.lowValue = LowValue (rank);

	this.toString   = function () {
		var code, color;
		switch (this.suit) 
		{ 
			case "C": code = "clubs"; color="black";
 break;

			case "D": code = "diams"; color="red"; break;
			case "H": code = "hearts"; color="red"; break;
			case "S": code = "spades"; color="black"; break;
		} 		
		return "&lt;font color=" + color +"&gt;" + this.rank + "&amp;" + code +";&lt;/font&gt;"; 
	}
}

function ComputeHandRank(hand)
{
	var high = 0, low = 0;
	for (var i=0;i&lt;hand.length;i++)
	{
		high += hand[i].highValue;
		low += hand[i].lowValue;
	}
	return high &lt;= 21 ? high : low; 	
}

function Deck () {
	
	function generateCards() {	
		var cards = new Array();
		var suits = "CDHS";
		for (var suit=0; suit&lt;suits.length; suit++)
		{
			var ranks = "A23456789JQK";
			for (var rank=0; rank&lt;ranks.length; rank++)
			{
				var card = new Card(ranks.charAt(rank), suits.charAt(suit));
				cards.push( card  );
			}	

		}
		return cards;	
	}

	function shuffle (cards) {
		var pairs = new Array();
		for (var i=0;i&lt;cards.length;i++)
		{
			pairs.push ( new Pair(Math.random(), cards[i]) );
		}
		pairs.sort( function (a,b) { return a.fst - b.fst; }	);	


		var shuffled = new Array();
		for (var i=0;i
&lt;pairs.length;i++)
		{		
			shuffled.push( pairs[i].snd );
		}
		return shuffled;
	}

	this.cards = shuffle( generateCards() );	 
	this.takeOne = function () { return this.cards.shift(); }
}

var deck, babyHand, userHand;

function Play()
{
	setTimeout( function () { player.URL= "http://www.trelford.com/BabyJack.gif"; clearTimeout();}, 100);
	player.controls.play ();
	var s = "&lt;input style=\"font-family:fantasy;font-size:20\" type=button onclick=\"Javascript:Shuffle();\" value=\"Play BabyJack!\"/&gt;";
	document.getElementById("Prompt").innerHTML = s;
}


function Shuffle()
{
	player.URL= "http://www.trelford.com/Shuffle.wmv";
	document.getElementById("Prompt").innerHTML = "Shuffling deck";
	deck = new Deck();
	babyHand = new Array();
	userHand = new Array();
	babyHand.push(deck.takeOne());
	userHand.push(deck.takeOne());
	babyHand.push(deck.takeOne());	
	userHand.push(deck.takeOne());

}

function StickOrTwist()
{
	var html = "Your cards " + userHand.join();
	if (userHand.length &gt; 2 &amp;&amp; ComputeHandRank (userHand) &gt; 21 )
	{
		html += " make you Bust";
		setTimeout( function () { player.URL = "http://www.trelford.com/Win.wmv"; clearTimeout(); }, 500);
	}
	else
 	{
		setTimeout( function () { player.URL= "http://www.trelford.com/StickOrTwist.gif"; clearTimeout(); }, 100);			
		html += " do you "; 
		html += "&lt;input style=\"font-family:fantasy;font-size:20\" type=button value=\"Stick\"/ onClick=\"Javascript:Stick();\"&gt;";
		html += "&amp;nbsp;or&amp;nbsp;"
		html += "&lt;input style=\"font-family:fantasy;font-size:20\" type=button value=\"Twist\"/ onClick=\"Javascript:Twist();\"&gt;";
	}
	document.getElementById("Prompt").innerHTML = html;	
}

function Stick()
{	
	if (ComputeHandRank (babyHand) &gt;= ComputeHandRank (userHand) )
	{
		document.getElementById("Prompt").innerHTML = "BabyJack wins with " + babyHand.join();
		player.URL = "http://www.trelford.com/Win.wmv";				
	}
	else
	{
		document.getElementById("Prompt").innerHTML = "BabyJack loses with " + babyHand.join();
		player.URL = "http://www.trelford.com/Lose.wmv";				
	}
}

function Twist()
{
	player.URL= "http://www.trelford.com/Card.wmv";
	document.getElementById("Prompt").innerHTML = "Dealing card";	
	userHand.push(deck.takeOne());
}

&lt;/SCRIPT&gt;

&lt;SCRIPT language=JScript event=playStateChange(newState) for=player&gt;
if (newState == 1) {
	if (player.URL.match ("Shuffle") != null) StickOrTwist ();
	if (player.URL.match ("Card") != null) StickOrTwist ();
	if (player.URL.match ("Win") != null) Play ();
	if (player.URL.match ("Lose") != null) Play ();
}
&lt;/SCRIPT&gt;

&lt;P&gt;For those of you interested in how it was done; the video was shot on a simple digital camera, and then sepia and film age&amp;nbsp;&lt;A class="" href="http://www.microsoft.com/windowsxp/using/moviemaker/create/addspecialfx.mspx#specialfx" mce_href="http://www.microsoft.com/windowsxp/using/moviemaker/create/addspecialfx.mspx#specialfx"&gt;effects&lt;/A&gt; were applied in&amp;nbsp;&lt;A class="" href="http://www.microsoft.com/windows/products/windowsvista/features/details/moviemaker.mspx" mce_href="http://www.microsoft.com/windows/products/windowsvista/features/details/moviemaker.mspx"&gt;Vista's Movie Maker&lt;/A&gt;, with sound generated by my eldest son &lt;A class="" href="http://www.youtube.com/watch?v=uapHhhQNdfk" mce_href="http://www.youtube.com/watch?v=uapHhhQNdfk"&gt;Thomas&lt;/A&gt; playing piano in the background. The stills were created&amp;nbsp;using Microsoft &lt;A class="" href="http://windowshelp.microsoft.com/Windows/en-US/help/f5feb1df-8dd7-4ab0-9f65-3c1c89a329ab1033.mspx" mce_href="http://windowshelp.microsoft.com/Windows/en-US/help/f5feb1df-8dd7-4ab0-9f65-3c1c89a329ab1033.mspx"&gt;Paint&lt;/A&gt; and the&amp;nbsp;Chiller font.&amp;nbsp;The video itself was embedded in the page using the &lt;A class="" href="http://msdn.microsoft.com/en-us/library/bb249579(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/bb249579(VS.85).aspx"&gt;Windows Media Player Control&lt;/A&gt;; and the interaction was coded&amp;nbsp;in &lt;A class="" href="http://www.w3schools.com/JS/" mce_href="http://www.w3schools.com/JS/"&gt;Javascript&lt;/A&gt; using trusty &lt;A class="" href="http://windowshelp.microsoft.com/Windows/en-NZ/Help/d85ed1d6-e6b7-468a-be39-9505c04ceb781033.mspx" mce_href="http://windowshelp.microsoft.com/Windows/en-NZ/Help/d85ed1d6-e6b7-468a-be39-9505c04ceb781033.mspx"&gt;Notepad&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;&lt;STRONG&gt;Phil Trelford&lt;/STRONG&gt;&lt;/EM&gt;&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3061129" width="1" height="1"&gt;</description><enclosure url="http://blogs.technet.com/apg/attachment/3061129.ashx" length="5794" type="text/html" /><category domain="http://blogs.technet.com/apg/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.technet.com/apg/archive/tags/Games/default.aspx">Games</category></item><item><title>Lunar Lander Retro Vector XNA 2.0 Game sample written in F#</title><link>http://blogs.technet.com/apg/archive/2008/05/11/lunar-lander-retro-vector-xna-2-0-game-sample-written-in-f.aspx</link><pubDate>Mon, 12 May 2008 00:36:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3053806</guid><dc:creator>apg</dc:creator><slash:comments>9</slash:comments><comments>http://blogs.technet.com/apg/comments/3053806.aspx</comments><wfw:commentRss>http://blogs.technet.com/apg/commentrss.aspx?PostID=3053806</wfw:commentRss><description>&lt;P&gt;While travelling to&amp;nbsp;Microsoft HQ in Redmond&amp;nbsp;earlier in the year for the annual TechFest&amp;nbsp;event - for some fun I decided to&amp;nbsp;have a go at writing a&amp;nbsp;small retro game in &lt;A class="" title=FSharp href="http://research.microsoft.com/fsharp/fsharp.aspx" mce_href="http://research.microsoft.com/fsharp/fsharp.aspx"&gt;F#&lt;/A&gt; using &lt;A class="" href="http://creators.xna.com/" mce_href="http://creators.xna.com/"&gt;XNA 2.0&lt;/A&gt;, and attached are the results. When&amp;nbsp;moving over&amp;nbsp;to Pacific time I usually find myself waking up at 4am for the first few days, leaving me with plenty of wide awake hours I wouldn't normally have to while away, and this is when the sample was born. I&amp;nbsp;decided on an implementation of&amp;nbsp;&lt;A class="" title="Lunar Lander Computer Game" href="http://en.wikipedia.org/wiki/Lunar_Lander_%28computer_game%29" mce_href="http://en.wikipedia.org/wiki/Lunar_Lander_%28computer_game%29"&gt;Lunar Lander&lt;/A&gt; basically because it is pretty simple both logically and graphically,&amp;nbsp;and at the same time fun and achievable in a&amp;nbsp;relatively short time. The&amp;nbsp;sample lets you play with a game pad or keyboard ('Z' and 'X' to rotate, Space to thrust), and to complete the game you must land on the long flat section before you run out of fuel&amp;nbsp;and hit the jagged terrain.&lt;/P&gt;
&lt;P&gt;&lt;IMG title="Lunar Lander XNA Game Screenshot" style="WIDTH: 500px; HEIGHT: 375px" height=375 alt="Lunar Lander XNA Game Screenshot" src="http://blogs.technet.com/photos/apg/images/3053799/500x375.aspx" width=500 mce_src="http://blogs.technet.com/photos/apg/images/3053799/500x375.aspx"&gt;&lt;/P&gt;
&lt;P&gt;For those interested, the source is attached to this post, which comprises a Visual Studio 2005 solution, a C# XNA 2.0 shell project to take advantage of the content pipeline for audio, an F# game implementation project and a small utility project to create terrain vectors from points in an image file. Please feel free to download and&amp;nbsp;play with it, in theory if you have XNA 2.0 and F#&amp;nbsp;installed then you should be able to just load the solution and press F5 to build and run.&amp;nbsp;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;&lt;EM&gt;Phillip Trelford&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3053806" width="1" height="1"&gt;</description><enclosure url="http://blogs.technet.com/apg/attachment/3053806.ashx" length="99988" type="application/x-zip-compressed" /><category domain="http://blogs.technet.com/apg/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.technet.com/apg/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.technet.com/apg/archive/tags/XNA/default.aspx">XNA</category><category domain="http://blogs.technet.com/apg/archive/tags/Games/default.aspx">Games</category></item><item><title>TrueSkill Through Time</title><link>http://blogs.technet.com/apg/archive/2008/04/05/trueskill-through-time.aspx</link><pubDate>Sat, 05 Apr 2008 15:59:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3029664</guid><dc:creator>apg</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.technet.com/apg/comments/3029664.aspx</comments><wfw:commentRss>http://blogs.technet.com/apg/commentrss.aspx?PostID=3029664</wfw:commentRss><description>&lt;P&gt;In December 2007, we published a &lt;A href="http://books.nips.cc/papers/files/nips20/NIPS2007_0931.ps.gz"&gt;paper&lt;/A&gt; about the application of &lt;A title="TrueSkill Homepage" href="http://www.research.microsoft.com/mlp/apg/trueskill.aspx" mce_href="http://www.research.microsoft.com/mlp/apg/trueskill.aspx"&gt;TrueSkill&lt;/A&gt; to all recorded data of professional and semi-professional Chess play from 1850 to 2006. The dataset can be obtained from &lt;A href="http://www.chessbase.com/shop/product.asp?pid=211&amp;amp;user=&amp;amp;coin="&gt;ChessBase&lt;/A&gt;. We are very happy to be able to release the &lt;A href="http://research.microsoft.com/fsharp/fsharp.aspx"&gt;F#&lt;/A&gt; source code that performed all these massive computations. A few things to bear in mind when running this code:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The full factor graph has ~30,000,000 factors and ~25,000,000 variables. At this size, the analysis is among the largest applications of (approximate) Bayesian inference to date. Nevertheless, the full message passing schedule allocates no more than 11 GB of memory and is run in under 20 minutes on an Intel Pentium 4 processor. These numbers hold for the adaptive draw margin model run on 3.5 million games.&lt;/LI&gt;
&lt;LI&gt;Due to the huge amount of results (&amp;gt;1,200,000 skills of all players in all their active years) we use SQL server to store the result set. Please let us know if you think a purely text based result output is needed and we will add it.&lt;/LI&gt;
&lt;LI&gt;There is a very interesting, related &lt;A href="http://math.bu.edu/people/mg/research/glicko.pdf"&gt;paper&lt;/A&gt; by Prof. &lt;A href="http://math.bu.edu/people/mg/research/glicko.pdf"&gt;Mark Glickman&lt;/A&gt; which analyses subset of this data (88 top players of all time).&lt;/LI&gt;&lt;/UL&gt;
&lt;P mce_keep="true"&gt;The attached ZIP file contains the entire source code which should compile without problems with &lt;A href="http://research.microsoft.com/research/downloads/Details/7ac148a7-149b-4056-aa06-1e6754efd36f/Details.aspx"&gt;F# 1.9.3.14&lt;/A&gt;. You can either load the solution in Visual Studio 2008 or simply run build.bat form the command line - in either case you will end up with a &lt;U&gt;chessanalysis.exe&lt;/U&gt; program or an &lt;U&gt;analysis.exe&lt;/U&gt; program. If you want to try out the application, we included the first 1,000 lines of match outcomes (this is part of the first 5 years of data we have).&lt;/P&gt;
&lt;P mce_keep="true"&gt;As for running the code, here are the parameter switches of the command line application:&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;B&gt;-no-safe&lt;/B&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Does not save results predictions (default: off)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;B&gt;-q&amp;nbsp;&lt;/B&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Verbosity level off; only works on single runs (default: on)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;B&gt;-N &amp;lt;int&amp;gt;&lt;/B&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; First N games only (default: ALL)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;B&gt;-delta &amp;lt;float&amp;gt;&lt;/B&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Maximum deviation in any marginal for convergence (default: 0.01)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;B&gt;-muS &amp;lt;float&amp;gt;&lt;/B&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Mean of prior skill belief (default: 1200)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;B&gt;-sigmaS &amp;lt;float&amp;gt;&lt;/B&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Standard deviation of prior skill belief (default: 400)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;B&gt;-muD &amp;lt;float&amp;gt;&lt;/B&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;Mean of prior draw margin belief (default: 300)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;B&gt;-sigmaD &amp;lt;float&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/B&gt;Standard deviation of prior draw margin belief (default: 100)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;B&gt;-beta &amp;lt;float&amp;gt;&lt;/B&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; Standard deviation of performance distr. (default: 600)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;B&gt;-tauS &amp;lt;float&amp;gt;&lt;/B&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Standard deviation of skill dynamics distr. (default: 40)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;B&gt;-tauD &amp;lt;float&amp;gt;&lt;/B&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Standard deviation of draw margin dynamics distr. (default: 10)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;B&gt;-server &amp;lt;string&amp;gt;&lt;/B&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SQL server name for output (default: 'camresapga01')&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;B&gt;-prefix &amp;lt;string&amp;gt;&lt;/B&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Table name prefix for output (default: 'Result')&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;B&gt;-db &amp;lt;string&amp;gt;&lt;/B&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Name of the database for output (default: 'ChessBase')&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;B&gt;-mf&lt;/B&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;Fixed draw margin (default)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;B&gt;-mf2&lt;/B&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Fixed draw margin with two factors for draw&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;B&gt;-maf&lt;/B&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Fixed draw margin with ADF (iterate per year)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;B&gt;-maf2&lt;/B&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;Fixed draw margin with pure ADF&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;B&gt;-mv&lt;/B&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Variable draw margin&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;B&gt;-as&lt;/B&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Single run (default)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;B&gt;-am&lt;/B&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Model selection&lt;/P&gt;
&lt;P mce_keep="true"&gt;So, a good first test is analysis.exe -no-safe SmallChessBase.csv.&lt;/P&gt;
&lt;P mce_keep="true"&gt;We are very interested to hear your feedback - both on the model, our paper and the F# code.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Update&lt;/STRONG&gt;: Following the release of the &lt;A href="http://msdn.microsoft.com/en-us/fsharp/default.aspx" mce_href="http://msdn.microsoft.com/en-us/fsharp/default.aspx"&gt;F# September 2008 CTP&lt;/A&gt; we have updated the source code to work with &lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=61ad6924-93ad-48dc-8c67-60f7e7803d3c&amp;amp;displaylang=en" mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyID=61ad6924-93ad-48dc-8c67-60f7e7803d3c&amp;amp;displaylang=en"&gt;F# 1.9.6.2&lt;/A&gt;. Also, we added one of the new features of F#, namely units-of-measure. Note that one can no longer accidentally pass the variance instead of the standard deviation beceause the former being of type &lt;FONT face="Courier New"&gt;float&amp;lt;ELOPoints^2&amp;gt;&lt;FONT face=Arial&gt;. We have also added full debug support so simply press F5 to experiment with the -no-safe SmallChessBase.csv option mentioned above.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Update&lt;/STRONG&gt;: We removed a reduant schedule creation in the function &lt;EM&gt;FixedDrawMarginADFAnalyse&lt;/EM&gt;. Thanks &lt;A class="" href="http://users.rsise.anu.edu.au/~xzhang/" mce_href="http://users.rsise.anu.edu.au/~xzhang/"&gt;to Henry (Xinhua) Zhang&lt;/A&gt;&amp;nbsp;for pointing out this mistake!&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;SMALL&gt;Ralf Herbrich &amp;amp; Thore Graepel&lt;/SMALL&gt;&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3029664" width="1" height="1"&gt;</description><enclosure url="http://blogs.technet.com/apg/attachment/3029664.ashx" length="30784" type="application/x-zip-compressed" /><category domain="http://blogs.technet.com/apg/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.technet.com/apg/archive/tags/Bayesian/default.aspx">Bayesian</category><category domain="http://blogs.technet.com/apg/archive/tags/Machine+Learning/default.aspx">Machine Learning</category><category domain="http://blogs.technet.com/apg/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.technet.com/apg/archive/tags/TrueSkill/default.aspx">TrueSkill</category><category domain="http://blogs.technet.com/apg/archive/tags/Development/default.aspx">Development</category></item><item><title>F# Custom Exceptions</title><link>http://blogs.technet.com/apg/archive/2008/01/17/f-custom-exceptions.aspx</link><pubDate>Fri, 18 Jan 2008 00:07:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:2755044</guid><dc:creator>apg</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.technet.com/apg/comments/2755044.aspx</comments><wfw:commentRss>http://blogs.technet.com/apg/commentrss.aspx?PostID=2755044</wfw:commentRss><description>&lt;P&gt;This&amp;nbsp;post&amp;nbsp;tries to explore exception handling in F# with custom exception types.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Some background on .Net exceptions&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Exceptions happen:&lt;/STRONG&gt; &lt;CITE&gt;"Programs must be able to uniformly handle errors that occur during execution. The common language runtime greatly assists the design of fault-tolerant software by providing a model for notifying programs of errors in a uniform way. All &lt;SPAN style="BACKGROUND-COLOR: yellow"&gt;.NET Framework operations indicate failure by throwing exceptions&lt;/SPAN&gt;."&lt;/CITE&gt;&amp;nbsp;- &lt;A href="http://msdn2.microsoft.com/en-us/library/5b2yeyab.aspx"&gt;.NET Framework Developer's Guide: Handling and Throwing Exceptions&lt;/A&gt;. 
&lt;LI&gt;&lt;STRONG&gt;Deal with them:&lt;/STRONG&gt; &lt;CITE&gt;"To build successful and flexible applications that can be maintained and supported easily, you must adopt an appropriate strategy for exception management. You must design your system to ensure that it is capable of the following:&amp;nbsp;&lt;/CITE&gt; 
&lt;UL&gt;
&lt;LI&gt;&lt;CITE&gt;&lt;SPAN style="BACKGROUND-COLOR: yellow"&gt;Detecting exceptions&lt;/SPAN&gt;.&lt;/CITE&gt; 
&lt;LI&gt;&lt;CITE&gt;Logging and reporting information.&lt;/CITE&gt; 
&lt;LI&gt;&lt;CITE&gt;Generating events that can be monitored externally to assist system operation."&lt;/CITE&gt;&lt;/LI&gt;&lt;/UL&gt;- &lt;A href="http://msdn2.microsoft.com/en-us/library/ms954599.aspx#emag__exception_management"&gt;Microsoft patterns &amp;amp; practices: Exception Management Architecture Guide&lt;/A&gt;. &lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;But:&lt;/STRONG&gt; &lt;CITE&gt;"&lt;SPAN style="BACKGROUND-COLOR: yellow"&gt;Do not rely on exceptions in your code.&lt;/SPAN&gt; Exceptions can cause performance to suffer significantly, so you should avoid using them as a way to control normal program flow. If it is possible to detect in code a condition that would cause an exception, do so rather than catching the exception itself and handling the condition."&lt;/CITE&gt;&amp;nbsp; -&amp;nbsp;&lt;A href="http://technet.microsoft.com/en-us/library/5dws599a(VS.80).aspx#CodingPractices"&gt;Microsoft TechNet:&amp;nbsp;Developing High-Performance ASP.NET Applications&lt;/A&gt;.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;And:&lt;/STRONG&gt; &lt;CITE&gt;"In most cases, &lt;SPAN style="BACKGROUND-COLOR: yellow"&gt;use the predefined exceptions types&lt;/SPAN&gt;. Define new exception types only for programmatic scenarios. Introduce a new exception class to enable a programmer to take a different action in code based on the exception class."&lt;/CITE&gt; - &lt;A href="http://msdn.microsoft.com/en-us/library/seyhszts.aspx"&gt;.Net Framework Developers Guide - Best Practices for Handling Exceptions&lt;/A&gt;.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Quick guide to F#&amp;nbsp;exception&amp;nbsp;handling keywords&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;
&lt;TABLE class="" cellSpacing=0 cellPadding=3 width="100%" border=0&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TH class=top align=left width="25%" class="top"&gt;F#&lt;/TH&gt;
&lt;TH class=top align=left width="25%" class="top"&gt;C# equivalent&lt;/TH&gt;
&lt;TH class=top align=left width="50%" class="top"&gt;Description&lt;/TH&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=odd class="odd"&gt;raise exception&lt;/TD&gt;
&lt;TD class=odd class="odd"&gt;&lt;A href="http://msdn2.microsoft.com/en-us/library/1ah5wsex.aspx"&gt;throw&lt;/A&gt; exception;&lt;/TD&gt;
&lt;TD class=odd class="odd"&gt;Throws the specified exception.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=even class="even"&gt;rethrow ()&lt;/TD&gt;
&lt;TD class=even class="even"&gt;&lt;A href="http://msdn2.microsoft.com/en-us/library/0yd65esw(VS.71).aspx"&gt;throw&lt;/A&gt;;&lt;/TD&gt;
&lt;TD class=even class="even"&gt;Rethrows the current&amp;nbsp;exception unchanged from a catch block.&lt;/TD&gt;&lt;/TD&gt;
&lt;TR&gt;
&lt;TD class=odd class="odd"&gt;try ... with&lt;/TD&gt;
&lt;TD class=odd class="odd"&gt;&lt;A href="http://msdn2.microsoft.com/en-us/library/0yd65esw.aspx"&gt;try-catch&lt;/A&gt;&lt;/TD&gt;
&lt;TD class=odd class="odd"&gt;Filters&amp;nbsp;exceptions.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=even class="even"&gt;try ... finally&lt;/TD&gt;
&lt;TD class=even class="even"&gt;
&lt;P&gt;&lt;A href="http://msdn2.microsoft.com/en-us/library/zwc8s4fz.aspx"&gt;try-finally&lt;/A&gt;&lt;/P&gt;&lt;/TD&gt;
&lt;TD class=even class="even"&gt;Guarantees&amp;nbsp;execution of specified final block.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=odd class="odd"&gt;failwith string&lt;/TD&gt;
&lt;TD class=odd class="odd"&gt;&amp;nbsp;&lt;/TD&gt;
&lt;TD class=odd class="odd"&gt;Throws a &lt;A href="http://research.microsoft.com/fsharp/manual/FSharp.Core/Microsoft.FSharp.Core.type_Failure.html"&gt;Failure&lt;/A&gt; exception with the specified string.&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;F#'s predifined library exceptions&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;
&lt;TABLE class="" cellSpacing=0 cellPadding=3 width="100%" border=0&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TH class=top align=left width="25%" class="top"&gt;Exception&lt;/TH&gt;
&lt;TH class=top align=left width="25%" class="top"&gt;Usage&lt;/TH&gt;
&lt;TH class=top align=left width="50%" class="top"&gt;Description&lt;/TH&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=odd class="odd"&gt;&lt;A href="http://research.microsoft.com/fsharp/manual/FSharp.Core/Microsoft.FSharp.Core.type_Failure.html"&gt;Failure&lt;/A&gt; of string&lt;/TD&gt;
&lt;TD class=odd class="odd"&gt;failwith "Bang!"&lt;/TD&gt;
&lt;TD class=odd class="odd"&gt;General failure.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=even class="even"&gt;&lt;A href="http://research.microsoft.com/fsharp/manual/FSharp.Core/Microsoft.FSharp.Core.type_InvalidArgument.html"&gt;InvalidArgument&lt;/A&gt;&amp;nbsp;of string&lt;/TD&gt;
&lt;TD class=even class="even"&gt;invalid_arg "arg1"&lt;/TD&gt;
&lt;TD class=even class="even"&gt;Invalid argument exception.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=odd class="odd"&gt;&lt;A href="http://research.microsoft.com/fsharp/manual/FSharp.Core/Microsoft.FSharp.Core.type__exn.html"&gt;exn&lt;/A&gt;&lt;/TD&gt;
&lt;TD class=odd class="odd"&gt;raise (new exn("Bang!"))&lt;/TD&gt;
&lt;TD class=odd class="odd"&gt;System.Exception type abbreviation.&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Filtering Failures &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Exceptions are caught/filtered&amp;nbsp;using&amp;nbsp;pattern matching and a Failure exception can be matched&amp;nbsp;like a &lt;A href="http://research.microsoft.com/fsharp/manual/quicktour.aspx#QuickTourDiscriminatedUnions"&gt;discriminated union &lt;/A&gt;type:&lt;/P&gt;&lt;PRE&gt;    &lt;SPAN style="COLOR: blue"&gt;try&lt;/SPAN&gt; failwith "Too many errors"
    &lt;SPAN style="COLOR: blue"&gt;with&lt;/SPAN&gt; | &lt;A class="" href="http://research.microsoft.com/fsharp/manual/FSharp.Core/Microsoft.FSharp.Core.type_Failure.html"&gt;Failure&lt;/A&gt; s &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;&lt;/SPAN&gt; printf "%s" s&lt;/PRE&gt;Outputs: "Too many errors" 
&lt;P&gt;&lt;STRONG&gt;Some reusable System.Exception based classes&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Frequently it is possible to simply reuse existing exception classes in your code:&lt;/P&gt;
&lt;TABLE class="" cellSpacing=0 cellPadding=3 width="100%" border=0&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TH class=top align=left width="25%" class="top"&gt;Exception class&lt;/TH&gt;
&lt;TH class=top align=left width="75%" class="top"&gt;Thrown when...&lt;/TH&gt;&lt;/TR&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=odd class="odd"&gt;&lt;A href="http://msdn2.microsoft.com/en-us/library/system.applicationexception.aspx"&gt;ApplicationException&lt;/A&gt;&lt;/TD&gt;
&lt;TD class=odd class="odd"&gt;a non-fatal application error occurs.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=even class="even"&gt;&lt;A href="http://msdn2.microsoft.com/en-us/library/system.argumentnullexception.aspx"&gt;ArgumentNullException&lt;/A&gt;&lt;/TD&gt;
&lt;TD class=even class="even"&gt;a null reference is passed to a method that does not accept it.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=odd class="odd"&gt;&lt;A href="http://msdn2.microsoft.com/en-us/library/system.argumentoutofrangeexception.aspx"&gt;ArgumentOutOfRangeException&lt;/A&gt;&lt;/TD&gt;
&lt;TD class=odd class="odd"&gt;the value of an argument is outside the allowable range of values.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=even class="even"&gt;&lt;A href="http://msdn2.microsoft.com/en-us/library/system.formatexception.aspx"&gt;FormatException&lt;/A&gt;&lt;/TD&gt;
&lt;TD class=even class="even"&gt;the format of an argument does not meet the parameter specifications.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=odd class="odd"&gt;&lt;A href="http://msdn2.microsoft.com/en-us/library/system.invalidoperationexception.aspx"&gt;InvalidOperationException&lt;/A&gt;&lt;/TD&gt;
&lt;TD class=odd class="odd"&gt;a method call is invalid for the object's current state.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=even class="even"&gt;&lt;A href="http://msdn2.microsoft.com/en-us/library/system.notimplementedexception.aspx"&gt;NotImplementedException&lt;/A&gt;&lt;/TD&gt;
&lt;TD class=even class="even"&gt;a requested method or operation is not implemented.&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;&lt;STRONG&gt;Custom F# exceptions&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;In some cases we&amp;nbsp;have a pragmatic reason to introduce our own custom exceptions, for example if we define our own data layer we may want to&amp;nbsp;have&amp;nbsp;an exception type for this layer.&amp;nbsp;In the same way the .Net&amp;nbsp;framework&amp;nbsp;defines&amp;nbsp;the &lt;A href="http://msdn2.microsoft.com/en-us/library/system.data.sqlclient.sqlexception.aspx"&gt;SqlException&lt;/A&gt; class&amp;nbsp;&amp;nbsp;for&amp;nbsp;SQL specific exceptions.&amp;nbsp;F# Custom exceptions&amp;nbsp;provide an extremely concise form definition like discriminated unions&amp;nbsp;which&amp;nbsp;makes them simarly&amp;nbsp;easy&amp;nbsp;to &lt;A class="" href="http://research.microsoft.com/fsharp/manual/quicktour.aspx#QuickTourPatterns" mce_href="http://research.microsoft.com/fsharp/manual/quicktour.aspx#QuickTourPatterns"&gt;pattern match&lt;/A&gt; against: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Defining a custom F# exception&lt;/STRONG&gt; &lt;PRE&gt;&lt;A href="http://research.microsoft.com/fsharp/manual/lexyacc.aspx#ExceptionDefns"&gt;exception&lt;/A&gt; AppException of string&lt;/PRE&gt;
&lt;LI&gt;
&lt;P&gt;&lt;STRONG&gt;Raising a custom F#&amp;nbsp;exception&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;&lt;PRE&gt;raise (AppException &lt;SPAN style="COLOR: #a31515"&gt;"Bang!"&lt;/SPAN&gt;)&lt;/PRE&gt;
&lt;LI&gt;
&lt;P&gt;&lt;STRONG&gt;Catching a custom F# exception&lt;/STRONG&gt;&lt;/P&gt;&lt;PRE&gt;&lt;SPAN style="COLOR: blue"&gt;try&lt;/SPAN&gt; raise (AppException &lt;SPAN style="COLOR: #a31515"&gt;"Bang!"&lt;/SPAN&gt;) &lt;SPAN style="COLOR: blue"&gt;with&lt;/SPAN&gt; | AppException s &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;&lt;/SPAN&gt; printf &lt;SPAN style="COLOR: #a31515"&gt;"%s"&lt;/SPAN&gt; s&lt;/PRE&gt;
&lt;P&gt;Outputs: "Bang!"&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI&gt;
&lt;P&gt;&lt;STRONG&gt;Reading the&amp;nbsp;Message property value of&amp;nbsp;a custom F# exception&lt;/STRONG&gt;&lt;BR.&gt; &lt;PRE&gt;&lt;SPAN style="COLOR: blue"&gt;try&lt;/SPAN&gt;&amp;nbsp;raise&amp;nbsp;(AppException &lt;SPAN style="COLOR: #a31515"&gt;"Bang!"&lt;/SPAN&gt;)&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;with&lt;/SPAN&gt; | e &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;&lt;/SPAN&gt; printf &lt;SPAN style="COLOR: #a31515"&gt;"%s"&lt;/SPAN&gt; e.Message&lt;/PRE&gt;
&lt;P&gt;Outputs: "Exn+AppException[System.String]..."&lt;/P&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;So this all seems to make F# custom exceptions&amp;nbsp;great for F# projects which are self-contained or which have F# projects as final consumers. However&amp;nbsp;F# custom exceptions&amp;nbsp;current concise construction syntax&amp;nbsp;does not allow&amp;nbsp;us to&amp;nbsp;pass the values for the &lt;A href="http://msdn2.microsoft.com/en-us/library/system.exception.message.aspx"&gt;Message&lt;/A&gt; and &lt;A href="http://msdn2.microsoft.com/en-us/library/system.exception.innerexception.aspx"&gt;InnerException&lt;/A&gt; properties&amp;nbsp;to&amp;nbsp;the underlying &lt;A href="http://msdn2.microsoft.com/en-us/library/system.exception.aspx"&gt;System.Exception&lt;/A&gt;. It is possible to override the System.Exception.Message property but then again we lose a lot of our original conciseness. So I think this means then that F# custom exceptions are probably not suitable&amp;nbsp;if&amp;nbsp;you are going to be throwing an exception&amp;nbsp;out of your F# project to say a C# project or&amp;nbsp;to a vanilla exception&amp;nbsp;logging mechanism.&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;An&amp;nbsp;Alternative - custom exceptions using plain old inheritance&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;You will see below&amp;nbsp;custom exceptions using inheritance are also&amp;nbsp;pretty concise for definition and for pattern matching and also allow you to&amp;nbsp;easily&amp;nbsp;initialize the &lt;A href="http://msdn2.microsoft.com/en-us/library/system.exception.aspx"&gt;System.Exception&lt;/A&gt;'s &lt;A href="http://msdn2.microsoft.com/en-us/library/system.exception.message.aspx"&gt;Message&lt;/A&gt; and &lt;A href="http://msdn2.microsoft.com/en-us/library/system.exception.innerexception.aspx"&gt;InnerException&lt;/A&gt; properties. Here we make good use of F#'s constructed classes, optional parameters and inheritance facilities:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Defining an F# custom exception&amp;nbsp;using inheritance&lt;/STRONG&gt; &lt;PRE&gt;&lt;SPAN style="COLOR: blue"&gt;type&lt;/SPAN&gt; VanillaException (message:string, ?innerException:exn) =
    &lt;SPAN style="COLOR: blue"&gt;inherit&lt;/SPAN&gt; ApplicationException (message, 
        &lt;SPAN style="COLOR: blue"&gt;match&lt;/SPAN&gt; innerException &lt;SPAN style="COLOR: blue"&gt;with&lt;/SPAN&gt; | Some(ex) &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;&lt;/SPAN&gt; ex | _ &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;&lt;/SPAN&gt; null)            &lt;/PRE&gt;
&lt;LI&gt;&lt;STRONG&gt;Pattern matching&amp;nbsp;exception types in F#&amp;nbsp;&lt;/STRONG&gt; &lt;PRE&gt;&lt;SPAN style="COLOR: blue"&gt;try&lt;/SPAN&gt; raise (new VanillaException(&lt;SPAN style="COLOR: #a31515"&gt;"Vanilla!"&lt;/SPAN&gt;)) 
&lt;SPAN style="COLOR: blue"&gt;with&lt;/SPAN&gt; 
| &lt;A href="http://research.microsoft.com/fsharp/manual/FSharp.Core/Microsoft.FSharp.Core.type_Failure.html"&gt;Failure&lt;/A&gt; s &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;&lt;/SPAN&gt; printf &lt;SPAN style="COLOR: #a31515"&gt;"%s"&lt;/SPAN&gt; s
| :? VanillaException as e &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;&lt;/SPAN&gt; printf &lt;SPAN style="COLOR: #a31515"&gt;"%s"&lt;/SPAN&gt; e.Message
| e &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;&lt;/SPAN&gt; e.Message&lt;/PRE&gt;Outputs: "Vanilla!"&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;So it appears&amp;nbsp;then that this approach&amp;nbsp;is&amp;nbsp;more suited&amp;nbsp;to F# originated frameworks and libraries that expose exceptions to other languages and/or logging frameworks. Finally I would recommend that in this case that you catch any F# custom exceptions at the application boundary including Failure exceptions and rethrow them as vanilla .Net exceptions. &lt;/P&gt;
&lt;P&gt;&lt;SMALL&gt;Phil Trelford&lt;/SMALL&gt;&lt;/P&gt;
&lt;P&gt;&lt;SMALL&gt;&lt;FONT size=2&gt;Further reading check out: &lt;A class="" href="http://www.springerlink.com/content/nm5235752hm3710r/?p=3d79f4935a564bbda0bb5c880edeb421&amp;amp;pi=3" mce_href="http://www.springerlink.com/content/nm5235752hm3710r/?p=3d79f4935a564bbda0bb5c880edeb421&amp;amp;pi=3"&gt;Expert F# Chapter 4 Introducing Imperative Programming&lt;/A&gt;.&lt;/FONT&gt;&lt;/SMALL&gt;&lt;/P&gt;&lt;/STRONG&gt;&lt;/STRONG&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=2755044" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/apg/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.technet.com/apg/archive/tags/Development/default.aspx">Development</category></item><item><title>Silicon Minds Challenge (+ submission sample) </title><link>http://blogs.technet.com/apg/archive/2007/12/23/silicon-minds.aspx</link><pubDate>Sun, 23 Dec 2007 22:47:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:2673521</guid><dc:creator>apg</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.technet.com/apg/comments/2673521.aspx</comments><wfw:commentRss>http://blogs.technet.com/apg/commentrss.aspx?PostID=2673521</wfw:commentRss><description>&lt;P&gt;On the&amp;nbsp;8th December 2007&amp;nbsp;the &lt;A class="" title="Silicon Minds" href="http://www.dreambuildplay.com/main/" mce_href="http://www.dreambuildplay.com/main/"&gt;Silicon Minds challenge&lt;/A&gt;&amp;nbsp;was launched at the &lt;A class="" title=MALAGA href="http://research.microsoft.com/mlp/apg/malaga.aspx" mce_href="http://research.microsoft.com/mlp/apg/malaga.aspx"&gt;Machine Learning and Games&amp;nbsp;workshop&lt;/A&gt;&amp;nbsp;of the &lt;A class="" href="http://nips.cc/" mce_href="http://nips.cc/"&gt;NIPS conference&lt;/A&gt; in the picturesque Canadian ski resort of Whistler. &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The challenge is to&amp;nbsp;push the limits of Artificial Intelligence while building a game with &lt;A class="" title="XNA Game Studio 2.0 Getting Started" href="http://creators.xna.com/Education/GettingStarted.aspx" mce_href="http://creators.xna.com/Education/GettingStarted.aspx"&gt;XNA Game Studio 2.0&lt;/A&gt;.&lt;/LI&gt;
&lt;LI&gt;The main prize an opportunity to interview for an internship with &lt;A class="" href="http://research.microsoft.com/cambridge/" mce_href="http://research.microsoft.com/cambridge/"&gt;Microsoft Research Cambridge&lt;/A&gt;, &lt;A class="" title=Rare href="http://www.rareware.com/" mce_href="http://www.rareware.com/"&gt;Rare Ltd&lt;/A&gt; or &lt;A class="" title=Lionhead href="http://www.lionhead.com/" mce_href="http://www.lionhead.com/"&gt;Lionhead Studios&lt;/A&gt;.&amp;nbsp;&lt;/LI&gt;
&lt;LI&gt;The&amp;nbsp;submission entry period lasts&amp;nbsp;until the 27th January 2008.&lt;/LI&gt;
&lt;LI&gt;Full details of the competition are available at the&amp;nbsp;DreamBuildPlay&amp;nbsp;website: &lt;A href="http://www.dreambuildplay.com/"&gt;http://www.dreambuildplay.com&lt;/A&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The contest is to be judged on 3 criteria:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN class=bold&gt;Game A.I. (60%)&lt;/SPAN&gt; – Game A.I. will be evaluated based on how it serves the game design, and how it contributes to the game experience. Novelty and originality of the AI is appreciated but not required: a novel use of an existing state-of-the AI method is in itself considered to be innovative. General applicability of the AI concepts/techniques is also valued.&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class=bold&gt;Fun Factor (20%)&lt;/SPAN&gt; – The fun factor will be evaluated based on how the game design creates a positive user experience. This may include how intellectually challenging, relaxing, stimulating or satisfying the game is. A key indicator for the fun factor will be the desire to keep playing.&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class=bold&gt;Production Quality (20%)&lt;/SPAN&gt; – Make your game world as polished as possible and hook your judges with exciting, entertaining action. Production quality will be evaluated based on how seamless the overall game play is, the quality of the assets used, and the structure, readability and level of documentation of the code.&lt;/LI&gt;&lt;/UL&gt;
&lt;P mce_keep="true"&gt;The submission must include the following:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Your finished game in .ccgame XNA Creators Club Game Package form.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;The source code and content of your game.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;A design summary.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Three screenshots of your finished game.&lt;/DIV&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P mce_keep="true"&gt;To this end over the last week we have been having fun creating a mini-sample submission attached based on the &lt;A class="" title="Board Game Go" href="http://en.wikipedia.org/wiki/Go_%28board_game%29" mce_href="http://en.wikipedia.org/wiki/Go_%28board_game%29"&gt;board game Go&lt;/A&gt; demonstrating:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Using Monte Carlo methods to score&amp;nbsp;the board - thanks to David Stern. &lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Some&amp;nbsp;well documented source - thanks to Ralf Herbrich. &lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;A sample design&amp;nbsp;summary - thanks to Thore Graepel.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Reused code and graphics - thanks to the &lt;A class="" title="Minjie sample" href="http://creators.xna.com/Headlines/minigames/archive/2007/03/07/Minjie.aspx" mce_href="http://creators.xna.com/Headlines/minigames/archive/2007/03/07/Minjie.aspx"&gt;XNA Minjie board game&amp;nbsp;sample&lt;/A&gt;. &lt;/DIV&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P mce_keep="true"&gt;Disclaimer: The mini-game sample itself actually uses a rule based AI and should not be seen as an example of AI or&amp;nbsp;game quality - more a sample of documentation quality and&amp;nbsp;the submission files required.&lt;/P&gt;
&lt;P mce_keep="true"&gt;What&amp;nbsp;we do hope is that you will find the sample a useful reference on how to document your code (specifically the XGoLibrary project), how to comment code you have&amp;nbsp;taken from other sources and how to write the design summary.&lt;/P&gt;
&lt;P mce_keep="true"&gt;On coding standards, if you are starting afresh for the competition we suggest you take a look at the MSDN&amp;nbsp;section &lt;A class="" title="Design Guidelines for Class Library Developers" href="http://msdn2.microsoft.com/en-us/library/czefa0ke(VS.71).aspx" mce_href="http://msdn2.microsoft.com/en-us/library/czefa0ke(VS.71).aspx"&gt;".Net Framework General Reference -&amp;nbsp;Design Guidelines for Class Library Developers"&lt;/A&gt; for guidance. In summary this is what we would like to see in the code:&amp;nbsp;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Readability chosen over raw performance.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Short understandable classes and functions.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;A consistent &lt;A class="" title="Naming Guidelines" href="http://msdn2.microsoft.com/en-us/library/xzf533w0(VS.71).aspx" mce_href="http://msdn2.microsoft.com/en-us/library/xzf533w0(VS.71).aspx"&gt;naming convention&lt;/A&gt;.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Good &lt;A class="" title="XML Documentation Comments (C# Programming Guide)" href="http://msdn2.microsoft.com/en-us/library/b2s063f7.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/b2s063f7.aspx"&gt;C# XML&amp;nbsp;comments&lt;/A&gt;.&lt;/DIV&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P mce_keep="true"&gt;Don't forget though 60% of the score is based on Game AI... hope you enjoy the contest - we are really looking forward to seeing your submitted games.&lt;/P&gt;
&lt;P mce_keep="true"&gt;Last&amp;nbsp;but not least&amp;nbsp;a quick special thanks to Joaquin Quiñonero Candela for working so hard organising the challenge.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;Update 1&lt;/STRONG&gt;: We have noticed that the PDF still had some review comments; they are removed now. Also, rendering during the scoring was accidently reset to constant black (rather than an alpha value proportional to the expected propability of the territory outcome). Finally, we slightly refined the passing algorithm of the AI: If the human player passes then the AI uses the Monte Carlo scorer to estimate whether or not each piece is already determined in colour up to a probability of at least 80%. If so, the AI passes already.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;Update 2&lt;/STRONG&gt;: We have noticed a couple of further bugs and easy improvements that can be made: The rule-based AI would start to fill in own eyes if the eye is either on the side of the board or in one of the four corners. This was not intended and has been fixe now. Also, the Monte Carlo sampling can be sped up significantly by only checking for move validity and "eye-ness" after a random move from the list of empty vertices has been determined. Checking a vertex for being empty is a lot faster than checking if a move is valid on that vertex.&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=2673521" width="1" height="1"&gt;</description><enclosure url="http://blogs.technet.com/apg/attachment/2673521.ashx" length="3503129" type="application/x-zip-compressed" /><category domain="http://blogs.technet.com/apg/archive/tags/Xbox+360/default.aspx">Xbox 360</category><category domain="http://blogs.technet.com/apg/archive/tags/Machine+Learning/default.aspx">Machine Learning</category><category domain="http://blogs.technet.com/apg/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.technet.com/apg/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.technet.com/apg/archive/tags/computer+Go/default.aspx">computer Go</category><category domain="http://blogs.technet.com/apg/archive/tags/XNA/default.aspx">XNA</category><category domain="http://blogs.technet.com/apg/archive/tags/Games/default.aspx">Games</category></item><item><title>Commercial Users of Functional Programming (CUFP) 2007</title><link>http://blogs.technet.com/apg/archive/2007/10/25/commercial-users-of-functional-programming-cufp-2007.aspx</link><pubDate>Fri, 26 Oct 2007 00:09:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:2252643</guid><dc:creator>apg</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.technet.com/apg/comments/2252643.aspx</comments><wfw:commentRss>http://blogs.technet.com/apg/commentrss.aspx?PostID=2252643</wfw:commentRss><description>&lt;P&gt;At the beginning of this month (October) I attended and presented at the &lt;A class="" href="http://cufp.galois.com/" mce_href="http://cufp.galois.com/"&gt;CUFP&lt;/A&gt;&amp;nbsp;event in Freiburg, Germany.&amp;nbsp;The &lt;A class="" href="http://cufp.galois.com/2007Abstracts.html#PhilTrelford" mce_href="http://cufp.galois.com/2007Abstracts.html#PhilTrelford"&gt;talk&lt;/A&gt; was on some of the work our group has been doing&amp;nbsp;over the last year&amp;nbsp;using &lt;A class="" href="http://research.microsoft.com/fsharp/" mce_href="http://research.microsoft.com/fsharp/"&gt;F#&lt;/A&gt;&amp;nbsp;including the XBox 360 title &lt;A class="" href="http://www.halo3.com/" mce_href="http://www.halo3.com/"&gt;Halo 3&lt;/A&gt;&amp;nbsp;and on predicting ad clicks for&amp;nbsp;&lt;A class="" href="http://www.live.com/" mce_href="http://www.live.com/"&gt;Windows Live&lt;/A&gt;. The &lt;A class="" href="http://cufp.galois.com/slides/2007/PhilTrelford.ppt" mce_href="http://cufp.galois.com/slides/2007/PhilTrelford.ppt"&gt;slides&lt;/A&gt; (thanks Ralf) are now available online and for those who couldn't make&amp;nbsp;it videos&amp;nbsp;of all the talks&amp;nbsp;are expected soon. There were plenty of interesting talks throughout the day, including Chris Waterson of Liveops "... using continuation passing monads to encapsulate computation state and hide the complexity of the non-blocking I/O layer"&amp;nbsp;with OCaml, which&amp;nbsp;seemed to be in&amp;nbsp;a&amp;nbsp;similar direction&amp;nbsp;to&amp;nbsp;&lt;A class="" href="http://blogs.msdn.com/dsyme/archive/2007/10/11/introducing-f-asynchronous-workflows.aspx" mce_href="http://blogs.msdn.com/dsyme/archive/2007/10/11/introducing-f-asynchronous-workflows.aspx"&gt;F# asynchronous workflows&lt;/A&gt;. The day ended with a discussion led by Don Syme on the subject of hiring functional programmers; where it emerged that the&amp;nbsp;remaining attendees were actively seeking over 40 new hires. Finally it was time to enjoy the remainder of a hot sunny day and&amp;nbsp;some quality German beer.&lt;/P&gt;
&lt;P&gt;Phil&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=2252643" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/apg/archive/tags/Xbox+360/default.aspx">Xbox 360</category><category domain="http://blogs.technet.com/apg/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.technet.com/apg/archive/tags/Xbox+Live/default.aspx">Xbox Live</category><category domain="http://blogs.technet.com/apg/archive/tags/Machine+Learning/default.aspx">Machine Learning</category><category domain="http://blogs.technet.com/apg/archive/tags/TrueSkill/default.aspx">TrueSkill</category><category domain="http://blogs.technet.com/apg/archive/tags/Development/default.aspx">Development</category></item><item><title>Composing a video game in F# </title><link>http://blogs.technet.com/apg/archive/2007/10/25/composing-a-video-game-in-f.aspx</link><pubDate>Thu, 25 Oct 2007 22:33:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:2251976</guid><dc:creator>apg</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.technet.com/apg/comments/2251976.aspx</comments><wfw:commentRss>http://blogs.technet.com/apg/commentrss.aspx?PostID=2251976</wfw:commentRss><description>&lt;P&gt;This week it was my opportunity to present a topic for&amp;nbsp;15 minutes&amp;nbsp;at the &lt;A class="" href="http://research.microsoft.com/mlp/" mce_href="http://research.microsoft.com/mlp/"&gt;MLP&lt;/A&gt; group's ritual Tuesday afternoon&amp;nbsp;tea and cakes session (yes - we are based in the UK). I thought it might be fun to knock up a little game&amp;nbsp;with&amp;nbsp;the Microsoft functional programming language &lt;A class="" href="http://research.microsoft.com/fsharp/" mce_href="http://research.microsoft.com/fsharp/"&gt;F#.&lt;/A&gt;&amp;nbsp;With only a few hours to spare at the weekend I decided to&amp;nbsp;go with&amp;nbsp;a retro style game and an old favourite of mine - the light cycle game sequence featured in the&amp;nbsp;80s&amp;nbsp;movie &lt;A class="" href="http://en.wikipedia.org/wiki/Tron_%28film%29" mce_href="http://en.wikipedia.org/wiki/Tron_%28film%29"&gt;Tron&lt;/A&gt;. So after about 4 hours I had a 2 player game in Windows Forms with optional support for&amp;nbsp;&lt;A class="" href="http://blogs.msdn.com/pstubbs/articles/531008.aspx" mce_href="http://blogs.msdn.com/pstubbs/articles/531008.aspx"&gt;XBox 360 controllers&amp;nbsp;with&amp;nbsp;managed DirectX&lt;/A&gt;&amp;nbsp;all in under 200 lines of F#; and come tea time I even had some players.&amp;nbsp;If you fancy having a go yourself&amp;nbsp;the code&amp;nbsp;can be viewed on&amp;nbsp;the &lt;A class="" href="http://www.strangelights.com/fsharp/wiki/default.aspx/FSharpWiki/LightCycles.html" mce_href="http://www.strangelights.com/fsharp/wiki/default.aspx/FSharpWiki/LightCycles.html"&gt;F# Wiki&lt;/A&gt;.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;IMG title="Light cycles" style="WIDTH: 601px; HEIGHT: 480px" height=480 alt="Light cycles" src="http://blogs.technet.com/photos/apg/images/2252066/601x480.aspx" width=601 mce_src="http://blogs.technet.com/photos/apg/images/2252066/601x480.aspx"&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Have fun,&lt;/P&gt;
&lt;P mce_keep="true"&gt;Phil&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=2251976" width="1" height="1"&gt;</description><enclosure url="http://blogs.technet.com/apg/attachment/2251976.ashx" length="7735" type="text/plain" /><category domain="http://blogs.technet.com/apg/archive/tags/Xbox+360/default.aspx">Xbox 360</category><category domain="http://blogs.technet.com/apg/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.technet.com/apg/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.technet.com/apg/archive/tags/Games/default.aspx">Games</category></item><item><title>Schedule Tasks in Windows XP </title><link>http://blogs.technet.com/apg/archive/2006/11/07/schedule-tasks-in-windows-xp.aspx</link><pubDate>Tue, 07 Nov 2006 11:54:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:505644</guid><dc:creator>apg</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.technet.com/apg/comments/505644.aspx</comments><wfw:commentRss>http://blogs.technet.com/apg/commentrss.aspx?PostID=505644</wfw:commentRss><description>&lt;P&gt;We have an F# console app which processes some gigabytes of data over a couple of hours. We wanted to run this on a specific machine daily in the early hours of the morning. The easy answer &lt;A href="http://support.microsoft.com/kb/308569" mce_href="http://support.microsoft.com/kb/308569"&gt;&lt;FONT color=#666699&gt;Windows XP's Scheduled Tasks&lt;/FONT&gt;&lt;/A&gt;. Just click &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;&lt;STRONG&gt;Start &amp;gt; All Programs &amp;gt; Accessories &amp;gt; System Tools &amp;gt; Scheduled Tasks&lt;/STRONG&gt;&lt;/EM&gt;.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;We also wanted a simple install mechanism for the script, dependencies and to schedule the task. Managing tasks can be automated from the command line with &lt;A href="http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/schtasks.mspx?mfr=true" mce_href="http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/schtasks.mspx?mfr=true"&gt;&lt;FONT color=#666699&gt;Schtasks.exe&lt;/FONT&gt;&lt;/A&gt; or a COM interface (see &lt;A href="http://www.codeproject.com/cs/library/taskschedulerlibrary.asp" mce_href="http://www.codeproject.com/cs/library/taskschedulerlibrary.asp"&gt;&lt;FONT color=#666699&gt;this CodeProject article&lt;/FONT&gt;&lt;/A&gt;). The command line option was taken for simplicity. A scheduled task could be created and deleted like this:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;STRONG&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt"&gt;&lt;FONT color=#000000&gt;&amp;gt; Schtasks.exe /Create /TN MorningDewey /TR "c:\windows\explorer.exe &lt;/FONT&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt"&gt;&lt;A href="http://www.msdewey.com/" mce_href="http://www.msdewey.com/"&gt;&lt;STRONG&gt;&lt;SPAN style="COLOR: #666699; FONT-FAMILY: 'Courier New'"&gt;http://www.msdewey.com&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'"&gt;&lt;FONT color=#000000&gt;" /SC DAILY /ST 09:00:00&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;B&gt;&lt;BR&gt;&lt;STRONG&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'"&gt;&lt;FONT color=#000000&gt;&amp;gt; Schtasks.exe /Delete /TN MorningDewey&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/B&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;When you create the task you may be prompted for your account password. If your task is command line only then you can use the /RU "System" option to run under the system account; this will not work for launching a GUI application. &lt;/P&gt;
&lt;P&gt;The whole solution was packaged up using &lt;A href="http://support.microsoft.com/kb/307353" mce_href="http://support.microsoft.com/kb/307353"&gt;&lt;FONT color=#666699&gt;Visual Studio Setup Project&lt;/FONT&gt;&lt;/A&gt; and a custom installer. The custom installer implements &lt;A href="http://msdn2.microsoft.com/en-us/library/system.configuration.install.installer(VS.80).aspx" mce_href="http://msdn2.microsoft.com/en-us/library/system.configuration.install.installer(VS.80).aspx"&gt;&lt;FONT color=#666699&gt;System.Configuration.Install.Installer&lt;/FONT&gt;&lt;/A&gt; with the Install and Uninstall methods invoking Schtasks.exe to create and delete the task respectively. The install directory can be deduced from the assemblypath context parameter:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; installDirectory = &lt;SPAN style="COLOR: teal"&gt;Directory&lt;/SPAN&gt;.GetCurrentDirectory();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// Try to get install directory from install assembly path&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.Context != &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; assemblyPath = &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.Context.Parameters[&lt;SPAN style="COLOR: maroon"&gt;"assemblypath"&lt;/SPAN&gt;];&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;installDirectory = &lt;SPAN style="COLOR: teal"&gt;Path&lt;/SPAN&gt;.GetDirectoryName(assemblyPath);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; taskPath = &lt;SPAN style="COLOR: teal"&gt;Path&lt;/SPAN&gt;.Combine(installDirectory, taskExecutable);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;I found that if the path to the task had any spaces the task would not execute under the scheduler; the answer was to convert the path to short name using the Win32 method &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/getshortpathname.asp" mce_href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/getshortpathname.asp"&gt;&lt;FONT color=#666699&gt;GetShortPathName&lt;/FONT&gt;&lt;/A&gt; and &lt;A href="http://www.pinvoke.net/default.aspx/kernel32.GetShortPathName" mce_href="http://www.pinvoke.net/default.aspx/kernel32.GetShortPathName"&gt;&lt;FONT color=#666699&gt;PInvoke&lt;/FONT&gt;&lt;/A&gt;. Finally a method to invoke &lt;A href="http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/schtasks.mspx?mfr=true" mce_href="http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/schtasks.mspx?mfr=true"&gt;&lt;FONT color=#666699&gt;Schtasks&lt;/FONT&gt;&lt;/A&gt; using the &lt;A href="http://msdn2.microsoft.com/en-us/library/system.diagnostics.process(VS.80).aspx" mce_href="http://msdn2.microsoft.com/en-us/library/system.diagnostics.process(VS.80).aspx"&gt;&lt;FONT color=#666699&gt;System.Diagnostics.Process&lt;/FONT&gt;&lt;/A&gt; class:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; RunCommandLine(&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; fileName, &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; arguments)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; workingDirectory = &lt;SPAN style="COLOR: teal"&gt;Directory&lt;/SPAN&gt;.GetCurrentDirectory();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: teal"&gt;Process&lt;/SPAN&gt; proc = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;Process&lt;/SPAN&gt;();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;using&lt;/SPAN&gt;(proc)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: teal"&gt;ProcessStartInfo&lt;/SPAN&gt; info = proc.StartInfo;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;info.UseShellExecute = &lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;info.RedirectStandardOutput = &lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;info.RedirectStandardError = &lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;info.CreateNoWindow = &lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;info.FileName = fileName;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;info.Arguments = arguments;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;info.WorkingDirectory = workingDirectory;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt;( proc.Start() )&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; output = proc.StandardOutput.ReadToEnd();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: teal"&gt;Debug&lt;/SPAN&gt;.WriteLine(output);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;proc.WaitForExit();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="FONT-SIZE: 7pt; FONT-FAMILY: Terminal; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SMALL&gt;&lt;A class="" href="http://research.microsoft.com/~phillipt/" target=_blank mce_href="http://research.microsoft.com/~phillipt/"&gt;Phillip Trelford&lt;/A&gt;&lt;/SMALL&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=505644" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/apg/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.technet.com/apg/archive/tags/Windows+XP/default.aspx">Windows XP</category><category domain="http://blogs.technet.com/apg/archive/tags/Development/default.aspx">Development</category></item><item><title>Dealing with Terabytes of Data in F#</title><link>http://blogs.technet.com/apg/archive/2006/11/04/dealing-with-terabytes-with-f.aspx</link><pubDate>Sat, 04 Nov 2006 11:04:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:495799</guid><dc:creator>apg</dc:creator><slash:comments>45</slash:comments><comments>http://blogs.technet.com/apg/comments/495799.aspx</comments><wfw:commentRss>http://blogs.technet.com/apg/commentrss.aspx?PostID=495799</wfw:commentRss><description>&lt;P&gt;In one of our current projects our algorithms we have to process close to 1 TB (&lt;A class="" href="http://en.wikipedia.org/wiki/Terabyte" target=_blank mce_href="http://en.wikipedia.org/wiki/Terabyte"&gt;Terabyte&lt;/A&gt;) of raw (ASCII) logs. Fortunately, the only analysis we need to do is to go once through all&amp;nbsp;the data and collect a small number of statistics per log line (think, for example counting the number of log lines that pass a certain criterion).&lt;/P&gt;
&lt;P&gt;With this type of dataset size it is out of question to read it all into memory and process it line-by-line. The central data structure of .Net/F# we are using is &lt;A class="" href="http://msdn2.microsoft.com/en-us/library/system.collections.ienumerable(VS.80).aspx" target=_blank mce_href="http://msdn2.microsoft.com/en-us/library/system.collections.ienumerable(VS.80).aspx"&gt;IEnumerable&lt;/A&gt;&amp;nbsp;- a memory efficient and lazy way of enumrating through collections of any type. Here a short piece of F# code that provides an IEnumerable for all log lines (using the new &lt;FONT face="Courier New"&gt;generate_using&lt;/FONT&gt; function that Don put into the standard library after my &lt;A class="" href="http://blogs.msdn.com/rherb/archive/2006/06/11/626145.aspx" target=_blank mce_href="http://blogs.msdn.com/rherb/archive/2006/06/11/626145.aspx"&gt;posting&lt;/A&gt;)&lt;/P&gt;&lt;FONT size=2&gt;
&lt;BLOCKQUOTE&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;#light&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;open&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; System.IO&lt;/SPAN&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;&lt;o:p&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;open&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; System.Collections.Generic&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="COLOR: green; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;/// Creates an IEnumrable through the lines of any text file. &lt;BR&gt;/// The function does not check &lt;/SPAN&gt;&lt;SPAN style="COLOR: green; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;if the file exists already!&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;let&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; CreateDataStream (fileName:string) = &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;IEnumerable.generate_using&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;( &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;fun&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; () &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;-&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;new&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; StreamReader (fileName) )&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;( &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;fun&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; reader &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;-&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;if&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; (reader.EndOfStream) &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;then&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; None &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;else&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; Some (reader.ReadLine()) )&lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;/P&gt;&lt;/FONT&gt;
&lt;P mce_keep="true"&gt;However, during development one often wants to run-and-test the code without having to wait for hours before the full Terabyte is processed - just to find that there is a one-off error in the counting. Of course, one could write a little helper tool that only takes the first, let's say, 10 Megabyte of the full data file and process this much smaller file in the development phase. However, this seems very inelegant and leads to a lot of replication of the same data on the file system. A much better way is to use this short function truncate&amp;nbsp;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;module&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; IEnumerable = &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;begin&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: green; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;/// Truncates a given IEnumerable&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;let&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; truncate n (x: #IEnumerable&amp;lt;'a&amp;gt;) =&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;IEnumerable.generate &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;( &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;fun&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; () &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;-&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; ref 0,x.GetEnumerator() ) &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;( &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;fun&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; (i,ie) &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;-&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;if&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; !i &amp;gt;= n &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;or&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; not (ie.MoveNext()) &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;then&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; None &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;else&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; (incr i; Some(ie.Current)) )&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;( &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;fun&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; (_,ie) &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;-&amp;gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; ie.Dispose () )&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;end&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;The nice thing with this truncation is that it has practically no computational over-head (other than testing and incrementing an integer) and does not cost any temporary memory. Here is a short piece of test-code for this function&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="COLOR: green; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;/// Test the truncate.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;do&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; [| 0;1;2;3;4;5;6;7;8;9 |] |&amp;gt; IEnumerable.truncate 4 |&amp;gt; IEnumerable.iter (printf &lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;"i = %d\n"&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;) &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;do&lt;/SPAN&gt;&lt;SPAN style="COLOR: windowtext; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; read_line () |&amp;gt; ignore&lt;/SPAN&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;&lt;SMALL&gt;Ralf Herbrich&lt;/SMALL&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;SMALL&gt;P.S.: Thanks to Don Syme and James Margetson for helping us with the truncate function!!!&lt;/SMALL&gt;&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=495799" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/apg/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.technet.com/apg/archive/tags/Development/default.aspx">Development</category></item></channel></rss>