<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Chris Smith's completely unique view</title><link>http://blogs.msdn.com/chrsmith/default.aspx</link><description>Algorithms, functional programming, CLR 4.0, and of course, F#!</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/ChrisSmithsCompletelyUniqueView" type="application/rss+xml" /><item><title>Lightweight PGN parser in F# – Part I</title><link>http://feedproxy.google.com/~r/ChrisSmithsCompletelyUniqueView/~3/BEQAXP-TVmc/lightweight-pgn-parser-in-f.aspx</link><pubDate>Sat, 13 Jun 2009 19:43:27 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9745849</guid><dc:creator>ChrSmith</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/chrsmith/comments/9745849.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chrsmith/commentrss.aspx?PostID=9745849</wfw:commentRss><description>&lt;p&gt;If you’ve ever spent a lot of time around the game of Chess you’ve probably seen or interacted with the PGN file format in one way or another. PGN stands for &lt;a href="http://en.wikipedia.org/wiki/Portable_Game_Notation"&gt;Portable Game Notation&lt;/a&gt; and is a concise way to represent Chess games.&lt;/p&gt;  &lt;p&gt;Using regular expressions I’ve written a very lightweight parser to handle the file format. I wouldn’t be surprised if the regular expressions don’t capture every legal .pgn file, but it shows how effective regular expressions can be for semi-structured data.&lt;/p&gt;  &lt;p&gt;Not being a Chess player myself, I’m not really sure what to do with: &lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: maroon"&gt;&amp;quot;Nxf7 Rxe1+&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;but perhaps I’ll look at that in a future blog post.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edit: On second thought, there is all sorts of wrong with this parser. For example, notice how move ‘3’ is listed twice. The ‘3…’ continues on after the comment.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Alas, once the raw list of moves is parsed another step to coalesce them is required. In addition, a commenter pointed out that the 1/2-1/2 is the result of the game (a draw). I’ll spend a little more time on this before I can call it an official ‘parser’ but it’s a nice start :D.&lt;/em&gt;&amp;#160; &lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;open &lt;/span&gt;System.Text.RegularExpressions

&lt;span style="color: blue"&gt;let &lt;/span&gt;pgnGameText = &lt;span style="color: maroon"&gt;&amp;quot;
[Event \&amp;quot;F/S Return Match\&amp;quot;]
[Site \&amp;quot;Belgrade, Serbia Yugoslavia|JUG\&amp;quot;]
[Date \&amp;quot;1992.11.04\&amp;quot;]
[Round \&amp;quot;29\&amp;quot;]
[White \&amp;quot;Fischer, Robert J.\&amp;quot;]
[Black \&amp;quot;Spassky, Boris V.\&amp;quot;]
[Result \&amp;quot;1/2-1/2\&amp;quot;]
 
1. e4 e5 2. Nf3 Nc6 3. Bb5 {This opening is called the Ruy Lopez.} 3... a6
4. Ba4 Nf6 5. O-O Be7 6. Re1 b5 7. Bb3 d6 8. c3 O-O 9. h3 Nb8  10. d4 Nbd7
11. c4 c6 12. cxb5 axb5 13. Nc3 Bb7 14. Bg5 b4 15. Nb1 h6 16. Bh4 c5 17. dxe5
Nxe4 18. Bxe7 Qxe7 19. exd6 Qf6 20. Nbd2 Nxd6 21. Nc4 Nxc4 22. Bxc4 Nb6
23. Ne5 Rae8 24. Bxf7+ Rxf7 25. Nxf7 Rxe1+ 26. Qxe1 Kxf7 27. Qe3 Qg5 28. Qxg5
hxg5 29. b3 Ke6 30. a3 Kd6 31. axb4 cxb4 32. Ra5 Nd5 33. f3 Bc8 34. Kf2 Bf5
35. Ra7 g6 36. Ra6+ Kc5 37. Ke1 Nf4 38. g3 Nxh3 39. Kd2 Kb5 40. Rd6 Kc5 41. Ra6
Nf2 42. g4 Bd3 43. Re6 1/2-1/2
&amp;quot;

&lt;/span&gt;&lt;span style="color: green"&gt;// Remove comments and markup from the PGN file
&lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;removeMarkup text = 
    &lt;span style="color: blue"&gt;let &lt;/span&gt;tagPairs = &lt;span style="color: blue"&gt;new &lt;/span&gt;Regex(&lt;span style="color: maroon"&gt;@&amp;quot;\[.*\]&amp;quot;&lt;/span&gt;)
    &lt;span style="color: blue"&gt;let &lt;/span&gt;noTagPairs = tagPairs.Replace(text, &lt;span style="color: maroon"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)

    &lt;span style="color: blue"&gt;let &lt;/span&gt;comments = &lt;span style="color: blue"&gt;new &lt;/span&gt;Regex(&lt;span style="color: maroon"&gt;@&amp;quot;\{.*\}&amp;quot;&lt;/span&gt;)
    &lt;span style="color: blue"&gt;let &lt;/span&gt;noComments = comments.Replace(noTagPairs, &lt;span style="color: maroon"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)
    
    &lt;span style="color: green"&gt;// Trim any leading whitespace and convert to a single-line
    &lt;/span&gt;noComments.Trim().Replace(&lt;span style="color: maroon"&gt;&amp;quot;\r&amp;quot;&lt;/span&gt;, &lt;span style="color: maroon"&gt;&amp;quot;&amp;quot;&lt;/span&gt;).Replace(&lt;span style="color: maroon"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;, &lt;span style="color: maroon"&gt;&amp;quot; &amp;quot;&lt;/span&gt;)
        
&lt;span style="color: green"&gt;// Get the list of moves, each prefixed with a number and one or three dots
&lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;getMoves text =
    &lt;span style="color: blue"&gt;let &lt;/span&gt;factRegex = &lt;span style="color: blue"&gt;new &lt;/span&gt;Regex(&lt;span style="color: maroon"&gt;@&amp;quot;\d+\.+&amp;quot;&lt;/span&gt;, RegexOptions.Multiline)
    factRegex.Split(text)

&lt;span style="color: blue"&gt;let &lt;/span&gt;normalizedText = removeMarkup pgnGameText
    
&lt;span style="color: blue"&gt;let &lt;/span&gt;printGameMoves() = 
    getMoves normalizedText
    |&amp;gt; Array.map (&lt;span style="color: blue"&gt;fun &lt;/span&gt;move &lt;span style="color: blue"&gt;-&amp;gt; &lt;/span&gt;move.Trim())
    |&amp;gt; Array.iteri (&lt;span style="color: blue"&gt;fun &lt;/span&gt;idx move &lt;span style="color: blue"&gt;-&amp;gt; &lt;/span&gt;printfn &lt;span style="color: maroon"&gt;&amp;quot;Move %2d: %s&amp;quot; &lt;/span&gt;idx move)
&lt;span style="color: green"&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;pre class="code"&gt;&lt;span style="color: green"&gt;(*
OUTPUT:

&amp;gt; printGameMoves();;
Move  0: 
Move  1: e4 e5
Move  2: Nf3 Nc6
Move  3: Bb5
Move  4: a6
Move  5: Ba4 Nf6
Move  6: O-O Be7
Move  7: Re1 b5
Move  8: Bb3 d6
Move  9: c3 O-O
Move 10: h3 Nb8
Move 11: d4 Nbd7
Move 12: c4 c6
Move 13: cxb5 axb5
Move 14: Nc3 Bb7
Move 15: Bg5 b4
Move 16: Nb1 h6
Move 17: Bh4 c5
Move 18: dxe5 Nxe4
Move 19: Bxe7 Qxe7
Move 20: exd6 Qf6
Move 21: Nbd2 Nxd6
Move 22: Nc4 Nxc4
Move 23: Bxc4 Nb6
Move 24: Ne5 Rae8
Move 25: Bxf7+ Rxf7
Move 26: Nxf7 Rxe1+
Move 27: Qxe1 Kxf7
Move 28: Qe3 Qg5
Move 29: Qxg5 hxg5
Move 30: b3 Ke6
Move 31: a3 Kd6
Move 32: axb4 cxb4
Move 33: Ra5 Nd5
Move 34: f3 Bc8
Move 35: Kf2 Bf5
Move 36: Ra7 g6
Move 37: Ra6+ Kc5
Move 38: Ke1 Nf4
Move 39: g3 Nxh3
Move 40: Kd2 Kb5
Move 41: Rd6 Kc5
Move 42: Ra6 Nf2
Move 43: g4 Bd3
Move 44: Re6 1/2-1/2
val it : unit = ()
*)&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9745849" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ChrisSmithsCompletelyUniqueView/~4/BEQAXP-TVmc" height="1" width="1"/&gt;</description><feedburner:origLink>http://blogs.msdn.com/chrsmith/archive/2009/06/13/lightweight-pgn-parser-in-f.aspx</feedburner:origLink></item><item><title>Programming F# – Official Cover</title><link>http://feedproxy.google.com/~r/ChrisSmithsCompletelyUniqueView/~3/EfKOx6fNHLs/programming-f-official-cover.aspx</link><pubDate>Thu, 14 May 2009 01:18:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9612832</guid><dc:creator>ChrSmith</dc:creator><slash:comments>22</slash:comments><comments>http://blogs.msdn.com/chrsmith/comments/9612832.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chrsmith/commentrss.aspx?PostID=9612832</wfw:commentRss><description>&lt;p&gt;So as it turns out my &lt;a href="http://blogs.msdn.com/chrsmith/archive/2009/02/02/petition-for-programming-f-s-book-cover.aspx"&gt;petition&lt;/a&gt; for a kickass cover was ultimately unsuccessful. But the good news is that I’m not suck with something neither cute nor cuddly. Instead I got a Jellyfish, after spending some time thinking about it is pretty good. (Though certainly not as awesome as a hydra.)&lt;/p&gt;  &lt;h1&gt;Jellyfish Facts&lt;/h1&gt;  &lt;ul&gt;   &lt;li&gt;Jellyfish can be found in every ocean. Therefore, in the time if trouble they can call on the &lt;a href="http://pirates.wikia.com/wiki/Pirate_Lord"&gt;nine pirate lords&lt;/a&gt; for help. Much like F# being able to use nine different programming paradigms and styles: &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;functional, imperative, object-oriented, metaprogramming, scripting, concurrent, reactive, declaritive, and awesome. (Yes, ‘awesome’ is a programming paradigm… and Haskell doesn’t support it.)&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Jellyfish do not have a brain or central nervous system. Just like F#… umm… you don’t need a nervous system to write world-class applications?&amp;#160; Let me get back to you on this one…&lt;/li&gt;    &lt;li&gt;The real reason I’m excited about having a Jellyfish on the cover is that they can &lt;strong&gt;Sting and Kill you&lt;/strong&gt;. Like F#, Jellyfish are deadly.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So anyways, this October be on the lookout for &lt;a href="http://oreilly.com/catalog/9780596801359/"&gt;Jellyfish Book&lt;/a&gt;!&lt;/p&gt;  &lt;p&gt;&lt;img alt="Programming F#: Rough Cuts Version" src="http://covers.oreilly.com/images/9780596801359/lrg.jpg" /&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9612832" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ChrisSmithsCompletelyUniqueView/~4/EfKOx6fNHLs" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/chrsmith/archive/tags/Programming+F_2300_/default.aspx">Programming F#</category><feedburner:origLink>http://blogs.msdn.com/chrsmith/archive/2009/05/13/programming-f-official-cover.aspx</feedburner:origLink></item><item><title>F# Scripting Zen – Bulk Updating Testcases</title><link>http://feedproxy.google.com/~r/ChrisSmithsCompletelyUniqueView/~3/IInN3Xg-Vo0/f-scripting-zen-bulk-updating-testcases.aspx</link><pubDate>Sat, 09 May 2009 17:35:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9599425</guid><dc:creator>ChrSmith</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/chrsmith/comments/9599425.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chrsmith/commentrss.aspx?PostID=9599425</wfw:commentRss><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;As the F# team is busy working to finish up &lt;A href="http://www.microsoft.com/visualstudio/en-us/products/2010/default.mspx"&gt;&lt;SPAN style="COLOR: blue"&gt;Visual Studio 2010&lt;/SPAN&gt;&lt;/A&gt;, one task left to complete is to localize the compiler, so that on a Japanese machine the error messages will be in Japanese.&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 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;While I’m sure a few &lt;A href="http://www.codinghorror.com/blog/archives/001248.html"&gt;&lt;SPAN style="COLOR: blue"&gt;Ugly American Programmers&lt;/SPAN&gt;&lt;/A&gt; might question the value of localized error messages, imagine if the F# compiler told you this every time you made a mistake:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;"&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;このタイプのパラメータ値を推定タイプ略語の安定の下では、消去されていません。このドロップ、または並べ替えのタイプのパラメータを、&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;のタイプは、例えば、略語の使用によるものです&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&amp;lt; ' a &amp;gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;を&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;= &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;はまたは&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;\ Ñ \ ttype&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;スワップ&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&amp;lt; '&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;は、&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt; ' b &amp;gt; = ' b * '&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;を&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;1&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;つの。&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;明示的にこの値の型のパラメータを宣言、&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt; \ Ñ&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;例：&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt; \ tlet&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;金&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&amp;lt; '&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;は、&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt; ' b &amp;gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;（&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;（&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt; x &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;、&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt; y &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;）に：スワップ&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&amp;lt; ' b &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;、&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt; ' a &amp;gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;を参照）&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;：スワップ&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&amp;lt; '&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;は、&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt; ' b &amp;gt; = &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;（イは、&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt; X &lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'MS Mincho'; mso-ansi-language: EN; mso-bidi-font-family: 'MS Mincho'"&gt;）&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;Anyways, my job is to update our F# compiler test automation to be localization agonistic. Meaning that tests will work just fine on both English, Japanese, and any of the other dozen or so languages Visual Studio gets localized to.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;The majority of our compiler automation works by taking a code file, compiling and running it, and if the process returns with a non-zero exit code report a failure. Negative tests - where we expect the code file not to compile – work by checking the compiler output for specific messages.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;The following is a sample F# compiler testcase. Note that the ‘expected message’ is an arbitrary regular expression, which is why the ‘(‘ and ‘)’ need to be escaped with a backslash.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;// FSB 1488, Implement redundancy checking for dynamic type test patterns&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;//&amp;lt;Expects status=warning&amp;gt;\(9,7-9,16\): warning FS0026: This rule will never be matched&amp;lt;/Expects&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; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;//&amp;lt;Expects status=warning&amp;gt;\(15,7-15,16\): warning FS0026: This rule will never be matched&amp;lt;/Expects&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; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;_ = &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;match &lt;/SPAN&gt;box &lt;SPAN style="COLOR: maroon"&gt;"3" &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;with &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;| :? string&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;1 &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;| :? string&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;1&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// check this rule is marked as 'never be matched'&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;| _ &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;2&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;_ = &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;match &lt;/SPAN&gt;box &lt;SPAN style="COLOR: maroon"&gt;"3" &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;with &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;| :? System.IComparable &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;1 &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;| :? string&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;1&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// check this rule is marked as 'never be matched'&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;| _ &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;2&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;exit 0&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;As you can probably guess, matching against English compiler output is problematic when testing a localized compiler. The F# QA team (consisting of 3 people) discussed a few options, but the design we settled on was simply encode more metadata into the ‘Expects’ tag, and simply not validate specific error text on non-English builds.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;So we want to rewrite all of our negative tests to look something like this:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;// FSB 1488, Implement redundancy checking for dynamic type test patterns&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;//&amp;lt;Expects &lt;B&gt;id="FS0026" span=(9,7-9,16) &lt;/B&gt;status="warning"&amp;gt;This rule will never be matched&amp;lt;/Expects&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; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;//&amp;lt;Expects &lt;B&gt;id="FS0026" span=(15,7-15,16)&lt;/B&gt; status="warning"&amp;gt;This rule will never be matched&amp;lt;/Expects&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; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;_ = &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;match &lt;/SPAN&gt;box &lt;SPAN style="COLOR: maroon"&gt;"3" &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;with &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;| :? string&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;1 &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;| :? string&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;1&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// check this rule is marked as 'never be matched'&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;| _ &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;2&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;_ = &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;match &lt;/SPAN&gt;box &lt;SPAN style="COLOR: maroon"&gt;"3" &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;with &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;| :? System.IComparable &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;1 &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;| :? string&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;1&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// check this rule is marked as 'never be matched'&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;| _ &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;2&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;exit 0&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;When the testcase is in this format, then rather than just matching the ‘message text’ we can build up the regular expression which we will match against the compiler output. So we will look for something like: &lt;I&gt;&amp;lt;span&amp;gt; + &amp;lt;message id&amp;gt; + &amp;lt;text&amp;gt;&lt;/I&gt;. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;Then, on localized installs we simply won’t match the text. (But still validate the line/column span of the error, and the error ID from the compiler.) This, combined with a little loc-specific testing, should be enough.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;So how do you fix the testbed? We have ~1,600 automated testcases which use the &amp;lt;Expects&amp;gt; technique, of those ~600 which need to be updated. As much as I love manually going through and tweaking formatting of testcases, hopefully I can put my F# knowledge to good use and whip up an &lt;A href="http://blogs.msdn.com/chrsmith/archive/tags/Scripting/default.aspx"&gt;&lt;SPAN style="COLOR: blue"&gt;F# script&lt;/SPAN&gt;&lt;/A&gt; do to this for me.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-outline-level: 1"&gt;&lt;B&gt;&lt;SPAN lang=EN style="FONT-SIZE: 24pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN; mso-font-kerning: 18.0pt"&gt;Defining Types&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;Before solving a problem in F#, the first step is usually defining new types. In this case, we want to create types to describe the metadata encoded in testcases.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;I’d like to draw your attention to how concise F#’s syntax is for declaring types. If this were C# you would need to sprinkle in property getters and setters, curly braces and semicolons. Instead, creating discriminated unions and records is straight forward. In addition, I’ve added a static Parse methods which we will use later.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;type &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;MessageType = &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;| Warning &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;| Error &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;| NotIn &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;| Success&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;override &lt;/SPAN&gt;this.ToString() =&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;match &lt;/SPAN&gt;this &lt;SPAN style="COLOR: blue"&gt;with&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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 lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;| Warning &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;"warning"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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 lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;| Error&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;"error"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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 lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;| NotIn&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;"notin"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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 lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;| Success &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;"success"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;static member &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;Parse(txt : string) =&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;match &lt;/SPAN&gt;txt.ToUpper() &lt;SPAN style="COLOR: blue"&gt;with&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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 lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;| &lt;SPAN style="COLOR: maroon"&gt;"WARNING" &lt;/SPAN&gt;| &lt;SPAN style="COLOR: maroon"&gt;"\"WARNING\"" &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;Warning&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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: maroon"&gt;"ERROR"&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;| &lt;SPAN style="COLOR: maroon"&gt;"\"ERROR\""&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;Error&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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: maroon"&gt;"NOTIN"&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;| &lt;SPAN style="COLOR: maroon"&gt;"\"NOTIN\""&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;NotIn&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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: maroon"&gt;"SUCCESS" &lt;/SPAN&gt;| &lt;SPAN style="COLOR: maroon"&gt;"\"SUCCESS\"" &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;Success&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;-&amp;gt; &lt;/SPAN&gt;failwithf &lt;SPAN style="COLOR: maroon"&gt;"Unknown message type: [%s]" &lt;/SPAN&gt;txt&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;type &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;MessageRange = &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;| NoRange&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// No error range specified&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;| OnePoint &lt;SPAN style="COLOR: blue"&gt;of &lt;/SPAN&gt;int * int&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="COLOR: green"&gt;// (a,b)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;| TwoPoints &lt;SPAN style="COLOR: blue"&gt;of &lt;/SPAN&gt;int * int * int * int &lt;SPAN style="COLOR: green"&gt;// (a,b-c,d)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;static member &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;Parse(txt : string) =&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;let &lt;/SPAN&gt;onePtRegex = &lt;SPAN style="COLOR: maroon"&gt;@".*\\\((\d+),(\d+)\\\).*"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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 lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;twoPtRegex = &lt;SPAN style="COLOR: maroon"&gt;@".*\\\((\d+),(\d+)-(\d+),(\d+)\\\).*"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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 lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;onePtMatch = Regex.Match(txt, onePtRegex)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;let &lt;/SPAN&gt;twoPtMatch = Regex.Match(txt, twoPtRegex)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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 style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;onePtMatch.Success &lt;SPAN style="COLOR: blue"&gt;then &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;OnePoint(int onePtMatch.Groups.[1].Value, int onePtMatch.Groups.[2].Value)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;elif &lt;/SPAN&gt;twoPtMatch.Success &lt;SPAN style="COLOR: blue"&gt;then &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;TwoPoints(int twoPtMatch.Groups.[1].Value, int twoPtMatch.Groups.[2].Value,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;int twoPtMatch.Groups.[3].Value, int twoPtMatch.Groups.[4].Value)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;else &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;NoRange&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;type &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;ExpectedMessage = &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;MsgType&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;: MessageType&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;MsgID&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;: string&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;MsgRange : MessageRange&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;MsgText&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;: string &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&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: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-outline-level: 1"&gt;&lt;B&gt;&lt;SPAN lang=EN style="FONT-SIZE: 24pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN; mso-font-kerning: 18.0pt"&gt;Parsing (AKA Regular Expression voodoo)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;Here comes the fun part: greping through each tescase file and trying to parse it using regular expressions. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;I’ll be honest when I say that we haven’t been super-consistent in how to encode error messages. So some tests have error spans, some don’t. Some match the error ID, some don’t. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;Admittedly this code could be better commented, but it should be pretty straight forward. Note that the removeTokens function could easily be rewritten to be a bunch of functions composed together (rather than using piplining). Having the separate ‘fixLineForm'X’ methods makes debugging a tad easier.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;/// Given the match string for a testcase strip out error spans and compiler error numbers.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;/// E.G.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;"\(9,18-9,21\): warning FS0035: This form of object expression is deprecated."&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;/// becomes: "This form of object expression is deprecated"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;removeTokens line =&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;fixLine regexPattern (groupIdx : int) line =&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;let &lt;/SPAN&gt;m =&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&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; &lt;/SPAN&gt;Regex.Match(&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;line,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;regexPattern)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;m.Success &lt;SPAN style="COLOR: blue"&gt;then&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;m.Groups.[groupIdx].Value&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;else&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;line&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// Specify error range (a,b-c,d): error FS????:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;fixLineForm1 = fixLine &lt;SPAN style="COLOR: maroon"&gt;@"\\\(\d+,\d+-\d+,\d+\\\)..(error|warning) FS\d\d\d\d..([^&amp;lt;]*)" &lt;/SPAN&gt;2&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// Specify error range (a,b): error FS????:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;fixLineForm2 = fixLine &lt;SPAN style="COLOR: maroon"&gt;"\\(\d+,\d+\\): (error|warning) FS\d\d\d\d..([^&amp;lt;]*)" &lt;/SPAN&gt;2&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// Start with error FS????:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;fixLineForm3 = fixLine &lt;SPAN style="COLOR: maroon"&gt;@"(error|warning) FS\d\d\d\d..([^&amp;lt;]*)" &lt;/SPAN&gt;2&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// Start with FS????:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;fixLineForm4 = fixLine &lt;SPAN style="COLOR: maroon"&gt;@"FS\d\d\d\d..([^&amp;lt;]*)" &lt;/SPAN&gt;1&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// Just error range (Note this must come before line form1)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;fixLineForm5 = fixLine &lt;SPAN style="COLOR: maroon"&gt;@"\\\(\d+,\d+-\d+,\d+\\\)..([^&amp;lt;]*)" &lt;/SPAN&gt;1&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// Just error FS????&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;fixLineForm6 = fixLine &lt;SPAN style="COLOR: maroon"&gt;@"(error|warning) FS\d\d\d\d([^&amp;lt;]*)" &lt;/SPAN&gt;2&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;line |&amp;gt; fixLineForm1 |&amp;gt; fixLineForm2 &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;|&amp;gt; fixLineForm3 |&amp;gt; fixLineForm4&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;|&amp;gt; fixLineForm5&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;/// If the line contains an &amp;lt;Expects&amp;gt; block, parse out the error ID, span, and text&lt;BR&gt;/// and rewrite it making them explicit.&lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;fixExpectedMessageLine line =&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;isMessageLineRegex = &lt;SPAN style="COLOR: maroon"&gt;"//.*&amp;lt;Expect[^&amp;gt;]*status=([^&amp;gt;]+)&amp;gt;([^&amp;lt;]*)&amp;lt;/Expect.+"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;m = Regex.Match(line, isMessageLineRegex)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;m.Success &lt;SPAN style="COLOR: blue"&gt;then&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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 lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;// If we've identified it as a line containing testcase metadata,&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;// parse it and rewrite it.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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 lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;message = &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;MsgType&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;= MessageType.Parse(m.Groups.[1].Value)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&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;MsgID&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;= (&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;id = Regex.Match(m.Groups.[2].Value, &lt;SPAN style="COLOR: maroon"&gt;".*(FS\d\d\d\d).*"&lt;/SPAN&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;&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;if &lt;/SPAN&gt;id.Success &lt;SPAN style="COLOR: blue"&gt;then &lt;/SPAN&gt;id.Groups.[1].Value&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;&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;else&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; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;"FS0191"&lt;/SPAN&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;MsgRange = MessageRange.Parse(m.Groups.[2].Value)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;MsgText&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;= removeTokens (m.Groups.[2].Value)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;let &lt;/SPAN&gt;spanPart = &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;match &lt;/SPAN&gt;message.MsgRange &lt;SPAN style="COLOR: blue"&gt;with&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;| NoRange&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;-&amp;gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;""&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;| OnePoint(x,y)&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;sprintf &lt;SPAN style="COLOR: maroon"&gt;"span=\"(%d,%d)\" " &lt;/SPAN&gt;x y&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;| TwoPoints(a,b,c,d) &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;sprintf &lt;SPAN style="COLOR: maroon"&gt;"span=\"(%d,%d,%d,%d)\" " &lt;/SPAN&gt;a b c d&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;message.MsgType = Error || message.MsgType = Warning &lt;SPAN style="COLOR: blue"&gt;then&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;sprintf&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;SPAN style="COLOR: maroon"&gt;"//&amp;lt;Expects id=\"%s\" %sstatus=\"%s\"&amp;gt;%s&amp;lt;/Expects&amp;gt;"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;message.MsgID spanPart (message.MsgType.ToString()) message.MsgText&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;else&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;// Only rewrite negative tests, skip SUCCESS or NOTIN tests...&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&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; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;line&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;else&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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 lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;// This line didn't contain any metadata information&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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 lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;line&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-outline-level: 1"&gt;&lt;B&gt;&lt;SPAN lang=EN style="FONT-SIZE: 24pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN; mso-font-kerning: 18.0pt"&gt;Fixing Testcases&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;The work to actually fix testcases requires a few utility functions. I’ll cover each one in order.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;First is my favorite four-line sequence expression: return all files under a given folder. Using yield! inside of a sequence expression is quite sexy.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let rec &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;filesUnder basePath =&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;seq {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;yield! &lt;/SPAN&gt;Directory.GetFiles(basePath)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;for &lt;/SPAN&gt;subDir &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;Directory.GetDirectories(basePath) &lt;SPAN style="COLOR: blue"&gt;do&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;yield! &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;filesUnder subDir }&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;Next is creating a type called FixedFile, which keeps track of any changes we made to the source code. (That is, if we need to rewrite any lines containing testcase metadata.) The code simply tries to modify each line, and if the updated array of strings is different then we know the file has been modified. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;You cannot compare two arrays to see if they are equal in C#, because it will use referential equality (comparing pointers.) The F# code on the other hand uses structural equality (comparing array elements).&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;type &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;FixedFile = { FilePath : string; FileFixed : bool; UpdatedLines : string[] }&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;fixFile filePath =&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;lines = File.ReadAllLines(filePath)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;fixedLines = lines |&amp;gt; Array.map fixExpectedMessageLine&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// Note use of structural equality&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;FilePath = filePath&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;FileFixed = (lines &amp;lt;&amp;gt; fixedLines)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;UpdatedLines = fixedLines &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&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: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;Next is a couple of functions to checkout a file for edit using using &lt;A href="http://en.wikipedia.org/wiki/Visual_SourceSafe#In-house_use"&gt;&lt;SPAN style="COLOR: blue"&gt;Source Depot&lt;/SPAN&gt;&lt;/A&gt;. (Shelling out to tf.exe to use &lt;A href="http://en.wikipedia.org/wiki/Team_Foundation_Server"&gt;&lt;SPAN style="COLOR: blue"&gt;Visual Studio Team Foundation Server&lt;/SPAN&gt;&lt;/A&gt; would work just as well.)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;/// Spawns a new process. Returns (exit code, stdout)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;shellExecute executablePath workingDir args =&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;let &lt;/SPAN&gt;startInfo = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;ProcessStartInfo()&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;startInfo.FileName&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;- executablePath&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;startInfo.WorkingDirectory &amp;lt;- workingDir&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;startInfo.Arguments&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;- args&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;startInfo.UseShellExecute&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;- &lt;SPAN style="COLOR: blue"&gt;false&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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 lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;startInfo.CreateNoWindow&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&amp;lt;- &lt;SPAN style="COLOR: blue"&gt;true&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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 lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;startInfo.RedirectStandardOutput &amp;lt;- &lt;SPAN style="COLOR: blue"&gt;true&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;proc = Process.Start(startInfo)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;proc.WaitForExit()&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;(proc.ExitCode, proc.StandardOutput.ReadToEnd())&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;/// Checks out a given file for edit&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;checkoutFile filePath =&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;printfn &lt;SPAN style="COLOR: maroon"&gt;"Checking out: %s" &lt;/SPAN&gt;filePath&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;pathToSD = &lt;SPAN style="COLOR: maroon"&gt;@"d:\Tools\SourceDepot\sd.exe"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;enlistmentPath = &lt;SPAN style="COLOR: maroon"&gt;@"D:\dd\cambridge_staging_3\src\"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;// Add working directory so SD knows which client to use...&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;let &lt;/SPAN&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;(ec, txt) = shellExecute pathToSD enlistmentPath (&lt;SPAN style="COLOR: maroon"&gt;"edit " &lt;/SPAN&gt;+ filePath)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&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: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;printfn &lt;SPAN style="COLOR: maroon"&gt;"SD exited with code %d\n%s" &lt;/SPAN&gt;ec txt&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&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: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-outline-level: 1"&gt;&lt;B&gt;&lt;SPAN lang=EN style="FONT-SIZE: 24pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN; mso-font-kerning: 18.0pt"&gt;Putting it Together&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;Unfortunately our script is somewhat anti-climactic. To fix all 600 compiler testcases the actual work is done in six lines of code:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; COLOR: maroon; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;@"D:\dd\cambridge_staging_3\src\tests\fsharpqa\Source"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;|&amp;gt; filesUnder&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;|&amp;gt; Seq.map fixFile&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;|&amp;gt; Seq.filter (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;fixedFile &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;fixedFile.FileFixed)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;|&amp;gt; Seq.iter (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;ff &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;checkoutFile ff.FilePath&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&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;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;File.WriteAllLines(ff.FilePath, ff.UpdatedLines))&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;So about 167 lines later, I have a script file that automates a task that would have easily taken a couple work days to complete. This F# script leveraged the existing IO and Regular Expressions libraries built into .NET, and can easily be packaged into a class library and shared with other developers. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 10pt; LINE-HEIGHT: normal; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN lang=EN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-fareast-font-family: 'Times New Roman'; mso-ansi-language: EN"&gt;So when you next encounter a problem you want to automate, consider looking to see if an F# script is the right solution for you.&lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9599425" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ChrisSmithsCompletelyUniqueView/~4/IInN3Xg-Vo0" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/chrsmith/archive/tags/Testing/default.aspx">Testing</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/Scripting/default.aspx">Scripting</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/Real+World/default.aspx">Real World</category><feedburner:origLink>http://blogs.msdn.com/chrsmith/archive/2009/05/09/f-scripting-zen-bulk-updating-testcases.aspx</feedburner:origLink></item><item><title>F# Community Roundup</title><link>http://feedproxy.google.com/~r/ChrisSmithsCompletelyUniqueView/~3/sAAHpaJ-nJI/f-community-roundup.aspx</link><pubDate>Tue, 05 May 2009 16:17:55 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9589147</guid><dc:creator>ChrSmith</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/chrsmith/comments/9589147.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chrsmith/commentrss.aspx?PostID=9589147</wfw:commentRss><description>&lt;p&gt;There’s plenty going on in the F# community these days, I figured I’d provide a shameless plug for few blog posts or videos I especially liked.&lt;/p&gt;  &lt;h2&gt;&lt;a href="http://groups.google.com/group/toronto-fsharp-study-group"&gt;Toronto F# Study Group&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;If you live in Soviet Canuckistan and are in the Toronto area, &lt;a href="http://blogs.objectsharp.com/CS/blogs/jlee/rss.aspx"&gt;Justin Lee&lt;/a&gt; is hosting an F# Study Group at the Dark Horse Cafe in Spadina on Thursday, May 7th.&lt;/p&gt;  &lt;h2&gt;&lt;a href="http://www.voyce.com/index.php/2009/04/24/il-analysis-using-fsharp/"&gt;IL analysis using F#&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;Ian Voyce looks (briefly) at some minimal F# code for picking apart the IL of a managed assembly. This is certainly something that I’d love to see more of in the future. &lt;/p&gt;  &lt;p&gt;To learn a bit more about IL, a great resource is &lt;a href="http://blogs.msdn.com/haibo_luo/default.aspx"&gt;Haibo Luo’s&lt;/a&gt; (now defunct) blog. &lt;/p&gt;  &lt;h2&gt;Jason Olson, the Tom Cruise of F#?&lt;/h2&gt;  &lt;p&gt;&lt;a href="http://www.managed-world.com/"&gt;Jason Olson&lt;/a&gt; F# lover and all around nice guy has been busy the past few weeks:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://channel9.msdn.com/posts/Charles/Jason-Olson-Composing-Programming-Languages-F-and-OO/"&gt;Interview for Channel 9 from Lang.NET&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://channel9.msdn.com/shows/10-4/10-4-Episode-17-F-Intro/"&gt;F# Intro screen cast&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;&lt;a href="http://tomasp.net/blog/imperative-ii-break.aspx"&gt;Imperative Computation in F#&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;Thomas Petricek has a great blog post up showing how you can create imperative constructs for F# code when using computation expressions. In short, you can add support for break and continue within while loops (just like C#).&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: green"&gt;// Counts '1, 3, 5, 7, 9'
&lt;/span&gt;imperative { 
    &lt;span style="color: blue"&gt;for &lt;/span&gt;x &lt;span style="color: blue"&gt;in &lt;/span&gt;1 .. 10 &lt;span style="color: blue"&gt;do 
        
        if &lt;/span&gt;x % 2 = 0 &lt;span style="color: blue"&gt;then 
            do! &lt;/span&gt;continue &lt;span style="color: green"&gt;// &amp;lt;---
            
        &lt;/span&gt;printfn &lt;span style="color: maroon"&gt;&amp;quot;number = %d&amp;quot; &lt;/span&gt;x 
}
 
&lt;span style="color: green"&gt;// Counts '1, 2, 3' and then stops   
&lt;/span&gt;imperative { 
    &lt;span style="color: blue"&gt;for &lt;/span&gt;x &lt;span style="color: blue"&gt;in &lt;/span&gt;1 .. 10 &lt;span style="color: blue"&gt;do

      if &lt;/span&gt;x &amp;gt;= 4 &lt;span style="color: blue"&gt;then 
        do! &lt;/span&gt;break &lt;span style="color: green"&gt;// &amp;lt;---

      &lt;/span&gt;printfn &lt;span style="color: maroon"&gt;&amp;quot;number = %d&amp;quot; &lt;/span&gt;!x
}&lt;/pre&gt;

&lt;p&gt;If you’d like to keep a better pulse on what the blogosphere has to say about F#, checkout the &lt;a href="http://feeds.feedburner.com/planet_fsharp"&gt;Planet F#&lt;/a&gt; RSS feed.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9589147" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ChrisSmithsCompletelyUniqueView/~4/sAAHpaJ-nJI" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/chrsmith/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/Shameless+Plugs/default.aspx">Shameless Plugs</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/Community/default.aspx">Community</category><feedburner:origLink>http://blogs.msdn.com/chrsmith/archive/2009/05/05/f-community-roundup.aspx</feedburner:origLink></item><item><title>Idiomatic F# – Functional vs. Imperative</title><link>http://feedproxy.google.com/~r/ChrisSmithsCompletelyUniqueView/~3/_irZe0zcjPE/idiomatic-f-functional-vs-imperative.aspx</link><pubDate>Thu, 23 Apr 2009 16:37:16 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9565043</guid><dc:creator>ChrSmith</dc:creator><slash:comments>11</slash:comments><comments>http://blogs.msdn.com/chrsmith/comments/9565043.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chrsmith/commentrss.aspx?PostID=9565043</wfw:commentRss><description>&lt;p&gt;&lt;/p&gt;  &lt;p&gt;Our story begins with this guy, Stuart Bowers, sipping functional programming cool aid out of a kickass mug from &lt;a href="http://www.cafepress.com/programmingfs"&gt;Cafe Press&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/IdiomaticFFunctionalvs.Imperative_F1FF/IMAGE_154_2.jpg"&gt;&lt;img title="IMAGE_154" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="244" alt="IMAGE_154" src="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/IdiomaticFFunctionalvs.Imperative_F1FF/IMAGE_154_thumb.jpg" width="184" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Stuart is a developer on &lt;a href="http://www.microsoft.com/amalga/default.mspx"&gt;Amalga&lt;/a&gt; and full-time F# developer at Microsoft. The world is at a loss because this man does not blog... &lt;/p&gt;  &lt;p&gt;Anyways, he has been reviewing chapters some chapters of &lt;a href="http://oreilly.com/catalog/9780596801359/"&gt;my book&lt;/a&gt; and we recently had a long conversation about what should be idiomatic F# style which I’d like to share. &lt;/p&gt;  &lt;h1&gt;The Problem&lt;/h1&gt;  &lt;p&gt;Question: What is the ‘correct F# way’ to write the following code:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Create a shared, mutable value and spawn two thread pool threads to sum elements in a list. (Intentionally creating a race condition, which was the point of the code example.)&lt;/p&gt; &lt;/blockquote&gt;  &lt;h2&gt;The Imperative (?) Way&lt;/h2&gt;  &lt;p&gt;Let’s start with how to do this imperatively.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;open &lt;/span&gt;System.Threading

&lt;span style="color: blue"&gt;let &lt;/span&gt;sumArray (arr : int[]) =
    &lt;span style="color: blue"&gt;let &lt;/span&gt;total = ref 0

    &lt;span style="color: green"&gt;// Add the first half
    &lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;thread1Finished = ref &lt;span style="color: blue"&gt;false
    &lt;/span&gt;ThreadPool.QueueUserWorkItem(
        &lt;span style="color: blue"&gt;fun &lt;/span&gt;_ &lt;span style="color: blue"&gt;-&amp;gt; for &lt;/span&gt;i = 0 &lt;span style="color: blue"&gt;to &lt;/span&gt;arr.Length / 2 - 1 &lt;span style="color: blue"&gt;do
                    &lt;/span&gt;total := arr.[i] + !total
                 thread1Finished := &lt;span style="color: blue"&gt;true
        &lt;/span&gt;) |&amp;gt; ignore

    &lt;span style="color: green"&gt;// Add the second half
    &lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;thread2Finished = ref &lt;span style="color: blue"&gt;false
    &lt;/span&gt;ThreadPool.QueueUserWorkItem(
        &lt;span style="color: blue"&gt;fun &lt;/span&gt;_ &lt;span style="color: blue"&gt;-&amp;gt; for &lt;/span&gt;i = arr.Length / 2 &lt;span style="color: blue"&gt;to &lt;/span&gt;arr.Length - 1 &lt;span style="color: blue"&gt;do
                    &lt;/span&gt;total := arr.[i] + !total
                 thread2Finished := &lt;span style="color: blue"&gt;true
        &lt;/span&gt;) |&amp;gt; ignore

    &lt;span style="color: green"&gt;// Wait while the two threads finish their work
    &lt;/span&gt;&lt;span style="color: blue"&gt;while &lt;/span&gt;!thread1Finished = &lt;span style="color: blue"&gt;false &lt;/span&gt;||
          !thread2Finished = &lt;span style="color: blue"&gt;false do

          &lt;/span&gt;Thread.Sleep(0)

    !total&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;The imperative code is very straight forward and offers a few benefits:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Simplicity. Not a whole lot is actually going on, just two calls to QueueUserWorkItem and a couple of boolean flags to keep track of when the threads complete.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, there are some drawbacks too:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Redundancy. Both lambdas passed to QueueUserWorkItem are essentially the same, so the code is duplicated. If you want to spice things up, such as adding logging you will either forget to update the code in both locations or simply add it twice.&lt;/li&gt;

  &lt;li&gt;Hidden data. The key difference between the two threads is the range of elements in the array that they sum. The first array counts 0 to len / 2 – 1, the second thread to len / 2 to len. However, this crucial fact is buried in the code in two separate places.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;The Functional (?) Way&lt;/h2&gt;

&lt;p&gt;&lt;span style="color: blue"&gt;&lt;font color="#333333"&gt;Now let’s examine how to do this in a more functional style.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;open &lt;/span&gt;System.Threading

&lt;span style="color: blue"&gt;let &lt;/span&gt;sumArray (arr : int[]) =
    &lt;span style="color: green"&gt;// Define a location in shared memory for counting
    &lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;total = ref 0

    &lt;span style="color: green"&gt;// Define two flags in shared memory
    &lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;thread1Finished, thread2Finished = ref &lt;span style="color: blue"&gt;false&lt;/span&gt;, ref &lt;span style="color: blue"&gt;false
    
    &lt;/span&gt;&lt;span style="color: green"&gt;// Generate a lambda to sum a section of the array. 
    &lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;sumElements (startIndex,endIndex) flag = 
          &lt;span style="color: blue"&gt;fun &lt;/span&gt;(_:obj) &lt;span style="color: blue"&gt;-&amp;gt; 
              for &lt;/span&gt;i = startIndex &lt;span style="color: blue"&gt;to &lt;/span&gt;endIndex &lt;span style="color: blue"&gt;do
                &lt;/span&gt;total := arr.[i] + !total
              flag := &lt;span style="color: blue"&gt;true  
    
    &lt;/span&gt;&lt;span style="color: green"&gt;// Divy up the array
    &lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;firstHalf  = 0,(arr.Length / 2 - 1)  
    &lt;span style="color: blue"&gt;let &lt;/span&gt;secondHalf = (snd firstHalf)+1,(arr.Length - 1)
    
    &lt;span style="color: green"&gt;// Generate Delegates to sum portions of the array
    &lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;thread1Delegate = sumElements  firstHalf  thread1Finished
    &lt;span style="color: blue"&gt;let &lt;/span&gt;thread2Delegate = sumElements  secondHalf thread2Finished
    
    [ thread1Delegate; thread2Delegate ]       &lt;span style="color: green"&gt;// Queue up the delegates     
    &lt;/span&gt;|&amp;gt; List.map ThreadPool.QueueUserWorkItem   &lt;span style="color: green"&gt;// Queue the use work items
    &lt;/span&gt;|&amp;gt; ignore                                  &lt;span style="color: green"&gt;// Ignore the results 
        
    // Wait while the two threads finish their work
    &lt;/span&gt;&lt;span style="color: blue"&gt;while &lt;/span&gt;!thread1Finished = &lt;span style="color: blue"&gt;false &lt;/span&gt;||
          !thread2Finished = &lt;span style="color: blue"&gt;false do

          &lt;/span&gt;Thread.Sleep(0)

    !total&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;Let me start with the drawbacks of this functional style first:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Too many values. There are seven let bindings in the function – presumably they are all important.&lt;/li&gt;

  &lt;li&gt;Concept count. This more functional way of doing thing certainly requires you to understand a bit about F# coding. (Mapping the thread code to a curried QueueUserWorkItem is pretty hot though.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While arguably obfuscated, the functional style offers some clear benefits:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Important data is called out. Rather than hard coding the ‘0 to len / 2’ and ‘len / 2 to len’ values, the bounds for which to sum array elements is called out explicitly and on consecutive lines. This makes declaring an off-by-one error much easier to spot and fix.&lt;/li&gt;

  &lt;li&gt;Code reuse. Rather than hard coding the two thread pool functions, a sumElements function is introduced which takes explicit bounds to sum.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Personally I’m partial to the simplicity of the first example, but the value in calling out the range values in the second example shouldn’t be discounted. One of the best things I like about F# is that being a multi-paradigm language there is usually more than one approach to solve a problem, meaning you have options.&lt;/p&gt;

&lt;p&gt;Thanks goes to Stuart for letting me post his code. I’m curious to hear what you think with regard to the two styles, please leave a comment and let me know what you think.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9565043" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ChrisSmithsCompletelyUniqueView/~4/_irZe0zcjPE" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/chrsmith/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/F_2300_+Design/default.aspx">F# Design</category><feedburner:origLink>http://blogs.msdn.com/chrsmith/archive/2009/04/23/idiomatic-f-functional-vs-imperative.aspx</feedburner:origLink></item><item><title>F# and the PFX Round 1</title><link>http://feedproxy.google.com/~r/ChrisSmithsCompletelyUniqueView/~3/TimH8LkG8IQ/f-and-the-pfx-round-1.aspx</link><pubDate>Wed, 08 Apr 2009 20:21:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9538885</guid><dc:creator>ChrSmith</dc:creator><slash:comments>11</slash:comments><comments>http://blogs.msdn.com/chrsmith/comments/9538885.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chrsmith/commentrss.aspx?PostID=9538885</wfw:commentRss><description>&lt;P&gt;I’m currently working on a chapter for &lt;A href="http://oreilly.com/catalog/9780596801359/" mce_href="http://oreilly.com/catalog/9780596801359/"&gt;Programming F#&lt;/A&gt; titled &lt;EM&gt;Asynchronous and Parallel Programming &lt;/EM&gt;which should turn out pretty well. Anyways, I have an example that was too awesome not to blog.&lt;/P&gt;
&lt;P&gt;In this post I’ll show how to use the Parallel Extensions to the .NET Framework for finding the shortest path between two nodes on a graph.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Problem Description&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Let’s say you are planning a road trip this summer, you will start in city X and travel to city Y. Since your car cannot fly, you cannot head straight to city Y. Instead, you need to find the shortest path from X to Y. (With bonus points for site seeing, like the &lt;A href="http://www.worldslargestthings.com/iowa/rocker.htm" mce_href="http://www.worldslargestthings.com/iowa/rocker.htm"&gt;World’s Largest Rocking Chair&lt;/A&gt; in Iowa)&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.ddj.com/security/187201451;jsessionid=NY1K313YWRT4GQSNDLRSKH0CJUNN2JVN?_requestid=588900" mce_href="http://www.ddj.com/security/187201451;jsessionid=NY1K313YWRT4GQSNDLRSKH0CJUNN2JVN?_requestid=588900"&gt;CS Gangstas&lt;/A&gt; have studied this problem and gave it the banal name ‘&lt;A href="http://en.wikipedia.org/wiki/Shortest_path_problem" mce_href="http://en.wikipedia.org/wiki/Shortest_path_problem"&gt;Shortest path problem&lt;/A&gt;’. If you do your research you can find plenty of clever and efficient algorithms; in this blog post I’ll just be solving this problem using a simple approach.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;The Algorithm&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/FTheParallelFXandFlyingacrosstheUS_78F6/image_2.png" mce_href="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/FTheParallelFXandFlyingacrosstheUS_78F6/image_2.png"&gt;&lt;IMG title=image style="BORDER-TOP-WIDTH: 0px; DISPLAY: inline; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=327 alt=image src="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/FTheParallelFXandFlyingacrosstheUS_78F6/image_thumb.png" width=553 border=0 mce_src="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/FTheParallelFXandFlyingacrosstheUS_78F6/image_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;The simplest way to solve this problem is create a dictionary of ‘shortest known path to city X’. Then, keep track of the cities you would like to visit and the distance traveled so far on that route. &lt;/P&gt;
&lt;P&gt;If you are at a city and the distance you have traveled so far exceeds the shortest known path, then return because you already know a shorter route to that city. &lt;/P&gt;
&lt;P&gt;Otherwise, update your ‘shortest known path’ data structure, and visit all of the city’s neighbors and repeat the process. Once you have exhaustively tried all paths the resulting ‘shortest known path’ data structure will contain the shortest path from your starting city to your final destination.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Lame Solution in C#&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Let’s try to quickly write this up in C#.&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN style="COLOR: blue"&gt;enum &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;City
    &lt;/SPAN&gt;{
        LosAngeles,
        Seattle, 
        &lt;SPAN style="COLOR: green"&gt;// [List cities here]
        &lt;/SPAN&gt;Boston,
        NewYork
    }

    &lt;SPAN style="COLOR: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;Initialize the routes between cities and the distances. 
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;/// &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;Example: int distTweenBostonAndChicago = x[Boston][Chicago];
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;static void &lt;/SPAN&gt;InitializeDistances(&lt;SPAN style="COLOR: #2b91af"&gt;Dictionary&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;City&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #2b91af"&gt;Dictionary&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;City&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;&amp;gt;&amp;gt; dist)
    {
        &lt;SPAN style="COLOR: green"&gt;// [Load your data here]
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;return new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Dictionary&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;City&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #2b91af"&gt;Dictionary&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;City&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;&amp;gt;&amp;gt;();
    }

    &lt;SPAN style="COLOR: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;Object to represent a route to a given city.
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Route
    &lt;/SPAN&gt;{
        &lt;SPAN style="COLOR: blue"&gt;public &lt;/SPAN&gt;Route()
        {
            DistanceTraveled = 0;
            Route = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;List&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;City&lt;/SPAN&gt;&amp;gt;();
        }
        &lt;SPAN style="COLOR: gray"&gt;/// &amp;lt;summary&amp;gt;
        /// &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;Add a new leg to an existing route.
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;/// &amp;lt;/summary&amp;gt;
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;public &lt;/SPAN&gt;Route(&lt;SPAN style="COLOR: #2b91af"&gt;Route &lt;/SPAN&gt;r, &lt;SPAN style="COLOR: #2b91af"&gt;City &lt;/SPAN&gt;nextCity, &lt;SPAN style="COLOR: blue"&gt;int &lt;/SPAN&gt;distance)
        {
            DistanceTraveled = r.DistanceTraveled + distance;
            Route = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;List&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;City&lt;/SPAN&gt;&amp;gt;(r.Route);
            Route.Add(nextCity);
        }
        &lt;SPAN style="COLOR: blue"&gt;public int &lt;/SPAN&gt;DistanceTraveled { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; &lt;SPAN style="COLOR: blue"&gt;set&lt;/SPAN&gt;; }
        &lt;SPAN style="COLOR: blue"&gt;public &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;List&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;City&lt;/SPAN&gt;&amp;gt; Route { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; &lt;SPAN style="COLOR: blue"&gt;set&lt;/SPAN&gt;; }
    }

    &lt;SPAN style="COLOR: gray"&gt;/// &amp;lt;summary&amp;gt;
    /// &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;This makes up for C# not having Tuples...
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: gray"&gt;/// &amp;lt;/summary&amp;gt;
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;CityToVisit
    &lt;/SPAN&gt;{
        &lt;SPAN style="COLOR: blue"&gt;public &lt;/SPAN&gt;CityToVisit(&lt;SPAN style="COLOR: #2b91af"&gt;City &lt;/SPAN&gt;c, &lt;SPAN style="COLOR: #2b91af"&gt;Route &lt;/SPAN&gt;r)
        {
            &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.City = c;
            &lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;.Route = r;
        }
        &lt;SPAN style="COLOR: blue"&gt;public &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;City &lt;/SPAN&gt;City { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; &lt;SPAN style="COLOR: blue"&gt;set&lt;/SPAN&gt;; }
        &lt;SPAN style="COLOR: blue"&gt;public &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Route &lt;/SPAN&gt;Route { &lt;SPAN style="COLOR: blue"&gt;get&lt;/SPAN&gt;; &lt;SPAN style="COLOR: blue"&gt;set&lt;/SPAN&gt;; }
    }

    &lt;SPAN style="COLOR: blue"&gt;static void &lt;/SPAN&gt;Main(&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;[] args)
    {
        &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;distTweenCities = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Dictionary&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;City&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #2b91af"&gt;Dictionary&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;City&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;&amp;gt;&amp;gt;();
        InitializeDistances(distTweenCities);

        &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;StartingCity = &lt;SPAN style="COLOR: #2b91af"&gt;City&lt;/SPAN&gt;.LosAngeles;
        &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;FinalDestination = &lt;SPAN style="COLOR: #2b91af"&gt;City&lt;/SPAN&gt;.NewYork;

        &lt;SPAN style="COLOR: green"&gt;// Keep track of the shorest paths to get from the starting city to
        // any other reachable city.
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;shortestPaths = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Dictionary&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;City&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #2b91af"&gt;Route&lt;/SPAN&gt;&amp;gt;();

        &lt;SPAN style="COLOR: green"&gt;// Initialize our 'cities to visit' list, begining at our start city having
        // traveled zero miles.
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;citiesToVisit = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Stack&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: #2b91af"&gt;CityToVisit&lt;/SPAN&gt;&amp;gt;();
        citiesToVisit.Push(&lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;CityToVisit&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #2b91af"&gt;City&lt;/SPAN&gt;.LosAngeles, &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Route&lt;/SPAN&gt;());


        &lt;SPAN style="COLOR: blue"&gt;while &lt;/SPAN&gt;(citiesToVisit.Count &amp;gt; 0)
        {
            &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;curLoc = citiesToVisit.Pop();

            &lt;SPAN style="COLOR: green"&gt;// Have we visited this city before? If not, then add it...
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(!shortestPaths.ContainsKey(curLoc.City))
                shortestPaths.Add(curLoc.City, nextCity.Route);

            &lt;SPAN style="COLOR: green"&gt;// Is the route we used to get here shorter than the best known?
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;(shortestPaths[curLoc.City] &amp;lt; curLoc.Route.DistanceTraveled)
            {
                &lt;SPAN style="COLOR: green"&gt;// Update our shortest paths...
                &lt;/SPAN&gt;shortestPaths[curLoc.City] = nextCity.Route;

                &lt;SPAN style="COLOR: green"&gt;// ... and visit all of its neighbors using this shortest path
                &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;foreach &lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;neighboringCity &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;distTweenCities[curLoc.City].Keys)
                {
                    &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;updatedRoute = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Route&lt;/SPAN&gt;(curLoc.Route, &lt;BR&gt;                                                 neighboringCity, &lt;BR&gt;                                                 distTweenCities[curLoc.City][neighboringCity];
                    &lt;SPAN style="COLOR: blue"&gt;var &lt;/SPAN&gt;cityToVisit = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;CityToVisit&lt;/SPAN&gt;(neighboringCity, updatedRoute); 
                    
                    citiesToVisit.Push(cityToVisit);
                }
            }
        }

        &lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;.WriteLine(&lt;SPAN style="COLOR: #a31515"&gt;"Shorest path from {0} to {1} is {2} miles."&lt;/SPAN&gt;,
                          StartingCity, FinalDestination, 
                          shortestPaths[StartingCity][FinalDestination]);
    }
}&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;&lt;FONT color=#009933&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Awesome Solution in F#&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;So while the above code solves the problem, it suffers two major setbacks. First, the algorithm behaves on order O(N^2), which means it is slow. This wouldn’t be as much of a problem if it weren’t for problem two: the implementation is single threaded. &lt;/P&gt;
&lt;P&gt;Being either slow or being single threaded is OK, but both at the same time is bad news.&lt;/P&gt;
&lt;P&gt;Fortunately in CLR 4.0 (&lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyId=348F73FD-593D-4B3C-B055-694C50D2B0F3&amp;amp;displaylang=en" mce_href="http://www.microsoft.com/downloads/details.aspx?FamilyId=348F73FD-593D-4B3C-B055-694C50D2B0F3&amp;amp;displaylang=en"&gt;and available on 3.5 in CTP form&lt;/A&gt;) the &lt;A href="http://blogs.msdn.com/pfxteam/default.aspx" mce_href="http://blogs.msdn.com/pfxteam/default.aspx"&gt;Parallel Extensions to the .NET Framework&lt;/A&gt; (PFX) make parallelizing code pretty simple.&lt;/P&gt;
&lt;P&gt;It is pretty clear how you to execute our algorithm in parallel, simple parallelize the process of visiting each city. The problem however comes when you are trying to read or write from the shorestPaths dictionary. Having multiple threads read and write from the same data structure at the same time is a recipe for disaster.&lt;/P&gt;
&lt;P&gt;However, the PFX contain some built-in collection types that are designed exactly for this sort of application. The PFX ConcurrentDictionary type acts and behaves just like a normal dictionary, except that you can safely use it in a concurrent environment. (I know that sounds really vague, I’ll write more about the benefits of the ConcurrentDictionary type in a later post.)&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Pedant’s Note: The solution locks on STDOUT so output messages don’t spew nonsense to the output; however this effectively makes the program run synchronously.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;open &lt;/SPAN&gt;System
&lt;SPAN style="COLOR: blue"&gt;open &lt;/SPAN&gt;System.Threading.Tasks
&lt;SPAN style="COLOR: blue"&gt;open &lt;/SPAN&gt;System.Collections.Generic
&lt;SPAN style="COLOR: blue"&gt;open &lt;/SPAN&gt;System.Collections.Concurrent
    
&lt;SPAN style="COLOR: blue"&gt;type &lt;/SPAN&gt;City = 
    | Boise     | LosAngeles    | NewYork   | Seattle
    | StLouis   | Phoenix       | Boston    | Chicago   
    | Denver
    
&lt;SPAN style="COLOR: green"&gt;// Known disances between US cities in miles. If there is a path from A to B,
// there is also a path from B to A. If no path is listed, then you cannot travel
// between the two cities.
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;distTweenCities = 
    &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;distances = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;Dictionary&amp;lt;City, Dictionary&amp;lt;City, int&amp;gt;&amp;gt;()
    
    [
        (Boise,   Seattle, 496);      (Boise,   Denver,  830);    
        (Boise,   Chicago, 1702);     (Seattle, LosAngeles, 1141); 
        (Seattle, Denver,  1321);     (LosAngeles, Denver,  1022);  
        (LosAngeles, Phoenix, 371);   (Phoenix, Denver,  809);      
        (Phoenix, StLouis, 1504);     (Denver,  StLouis, 8588);     
        (Denver,  Chicago, 1009);     (Chicago, NewYork, 811);     
        (Chicago, Boston,  986);      (StLouis, Chicago, 300);
        (Boston, StLouis,  986);      (NewYork, Boston,  211)
    ]
    &lt;SPAN style="COLOR: green"&gt;// Convert the list of links between cities into a dictionary
    &lt;/SPAN&gt;|&amp;gt; List.iter (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;(cityA, cityB, dist) &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; 
        
        if &lt;/SPAN&gt;not &amp;lt;| distances.ContainsKey(cityA) &lt;SPAN style="COLOR: blue"&gt;then
            &lt;/SPAN&gt;distances.Add(cityA, &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;Dictionary&amp;lt;City, int&amp;gt;())
        &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;not &amp;lt;| distances.ContainsKey(cityB) &lt;SPAN style="COLOR: blue"&gt;then
            &lt;/SPAN&gt;distances.Add(cityB, &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;Dictionary&amp;lt;City, int&amp;gt;())
            
        distances.[cityA].Add(cityB, dist)
        distances.[cityB].Add(cityA, dist))
        
    &lt;SPAN style="COLOR: green"&gt;// Return our dictionary of dictionaries of distances
    &lt;/SPAN&gt;distances

&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;stdout = Console.Out

&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;shortestPathBetween startingCity finalDestination =
    
    &lt;SPAN style="COLOR: green"&gt;// Keep track of the shorest path from 'startCity' to a given city, and
    // the path used to get to that city.
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;shortestPaths = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;ConcurrentDictionary&amp;lt;City, int * City list&amp;gt;()
    
    &lt;SPAN style="COLOR: blue"&gt;let rec &lt;/SPAN&gt;searchForShortestPath curCity distanceSoFar citiesVisitedSoFar = 

        &lt;SPAN style="COLOR: green"&gt;// Visit all available cities from the current city
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;visitAvailableDestinations() =
            
            &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;availableDestinations = distTweenCities.[curCity]
            
            &lt;SPAN style="COLOR: green"&gt;// Loop through destinations and spawn new tasks
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;for &lt;/SPAN&gt;dest &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;availableDestinations.Keys &lt;SPAN style="COLOR: blue"&gt;do
                &lt;/SPAN&gt;Task.Factory.StartNew(
                    &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;Action(&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;() &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; 
                        &lt;/SPAN&gt;searchForShortestPath 
                            dest 
                            (distTweenCities.[curCity].[dest] + distanceSoFar) 
                            (citiesVisitedSoFar @ [dest])
                )) |&amp;gt; ignore

        &lt;SPAN style="COLOR: green"&gt;// Have I already found a way to travel to this city?
        &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;visitedBefore = shortestPaths.ContainsKey(curCity)
        
        &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;not visitedBefore &lt;SPAN style="COLOR: blue"&gt;then
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// First time visiting this city, add to our 'visited cities'
            &lt;/SPAN&gt;shortestPaths.TryAdd(curCity, (distanceSoFar, citiesVisitedSoFar))
            
            lock stdout 
                 (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;() &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;printfn 
                                &lt;SPAN style="COLOR: maroon"&gt;"Origional route to %A (%d) via: %A" 
                                &lt;/SPAN&gt;curCity distanceSoFar citiesVisitedSoFar)

            
            visitAvailableDestinations()
        &lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// We have visited this city before, let's see if this route is faster
            &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;shortestKnownPath, cities = shortestPaths.[curCity]
            
            &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;distanceSoFar &amp;lt; shortestKnownPath &lt;SPAN style="COLOR: blue"&gt;then
                &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// Update shortest path, revisit neighboring cities
                &lt;/SPAN&gt;shortestPaths.[curCity] &amp;lt;- (distanceSoFar, citiesVisitedSoFar)
                
                lock stdout 
                     (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;() &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;printfn 
                                    &lt;SPAN style="COLOR: maroon"&gt;"Found shorter route to %A (%d) via:  %A" 
                                    &lt;/SPAN&gt;curCity distanceSoFar citiesVisitedSoFar)
                
                visitAvailableDestinations()
            &lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// Ignore, we have already found a faster way to get here
                &lt;/SPAN&gt;()

    &lt;SPAN style="COLOR: green"&gt;// Create the master task to find the shortest path between the two cities
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;t = 
        Task.Factory.StartNew(
            &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;Action(&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;() &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;searchForShortestPath startingCity 0 [])
        )
    t.Wait()
    
    &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;dist, path = shortestPaths.[finalDestination]
    
    printfn 
        &lt;SPAN style="COLOR: maroon"&gt;"The shortest distance from %A to %A is %d miles, with route:\n%A" 
        &lt;/SPAN&gt;startingCity finalDestination 
        dist path&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9538885" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ChrisSmithsCompletelyUniqueView/~4/TimH8LkG8IQ" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/chrsmith/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/PFX/default.aspx">PFX</category><feedburner:origLink>http://blogs.msdn.com/chrsmith/archive/2009/04/08/f-and-the-pfx-round-1.aspx</feedburner:origLink></item><item><title>Book Update – NEW Coauthor!</title><link>http://feedproxy.google.com/~r/ChrisSmithsCompletelyUniqueView/~3/Q-WwP_NhAsI/book-update-new-coauthor.aspx</link><pubDate>Thu, 02 Apr 2009 02:28:03 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9528396</guid><dc:creator>ChrSmith</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/chrsmith/comments/9528396.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chrsmith/commentrss.aspx?PostID=9528396</wfw:commentRss><description>&lt;p&gt;You might be concerned about my lack of blogging, perhaps that I was lost in the woods and perhaps eaten by a bear. Well, unfortunately, all of my time has been devoted to three tasks:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Writing &lt;em&gt;&lt;a href="http://oreilly.com/catalog/9780596801359/"&gt;Programming F#&lt;/a&gt;&lt;/em&gt; &lt;/li&gt;    &lt;li&gt;Passing &lt;a href="http://www.cs.washington.edu/education/courses/csep505/09wi/"&gt;Programming Languages&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Shipping &lt;a href="http://blogs.msdn.com/chrsmith/archive/2008/12/10/f-no-longer-vaporware.aspx"&gt;F# in Dev10&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I would like to give you an update on item #1 my book, as there have been some rather interesting developments. There are plenty of great books on F# being written, and book competition is a great thing. However, one F#-related book in particular has caught my attention:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;&lt;a href="http://www.manning.com/petricek/"&gt;Real World Functional Programming&lt;/a&gt;&lt;/h1&gt;  &lt;p&gt;By &lt;a href="http://tomasp.net/"&gt;Tomas Petricek&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/BookUpdate_B333/clip_image001_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image001" border="0" alt="clip_image001" src="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/BookUpdate_B333/clip_image001_thumb.jpg" width="154" height="192" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Tomas currently works as an intern at Microsoft Research in Cambridge on F# and is crazy-smart. (Seriously, he’s a level-9 ninja master at F#. Have you checked out &lt;a href="http://www.codeplex.com/fswebtools"&gt;F# Web Tools?&lt;/a&gt;) &lt;/p&gt;  &lt;p&gt;But I’m not too worried about my book competing with his for two reasons:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;His book is about Functional Programming and mine is specifically about F#. So while there is some overlap, his book is about applications of functional programming while mine is about concepts and syntax. &lt;/li&gt;    &lt;li&gt;His has some creepy looking dude* and mine will (&lt;a href="http://blogs.msdn.com/chrsmith/archive/2009/02/02/petition-for-programming-f-s-book-cover.aspx"&gt;hopefully&lt;/a&gt;) have a fire-breathing Hydra on the cover. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;For a time I wasn’t worried about Tomas’ book. Until now…&lt;/p&gt;  &lt;p&gt;It was &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2009/02/27/current-book-project-real-world-functional-programming.aspx"&gt;recently announced&lt;/a&gt; that Manning was adding a co-author to Tomas’ book; none other than &lt;a href="http://msmvps.com/blogs/jon_skeet/default.aspx"&gt;Jon Skeet&lt;/a&gt; himself. Make no mistake, Jon is not some mortal programmer. Rather, his brain &lt;a href="http://stackoverflow.com/users/22656/jon-skeet"&gt;contains 63.8% of all knowledge on StackOverflow&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;So &lt;em&gt;Real World Functional Programming&lt;/em&gt; not only has one great authoring. But now it has &lt;strong&gt;two&lt;/strong&gt;. So really, any other book on F# or functional programming is simply hosed. No point in publishing it – Tomas Petricek and Jon Skeet are teaming up to write a book on functional programming. Save your time and go home.&lt;/p&gt;  &lt;p&gt;I don’t mind the challenge of competing with this book, but it certainly raises the stakes. &lt;/p&gt;  &lt;p&gt;I’ve been making a few phone calls to &lt;a href="http://www.oreillynet.com/pub/au/27"&gt;Tim O’Reilly&lt;/a&gt; and &lt;a href="http://twitter.com/laurelatoreilly"&gt;Laurel Ruma&lt;/a&gt; about what we can do about this. It took a while to get layers to figure things out, but now I have a new coauthor of my own for &lt;em&gt;Programming F#&lt;/em&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/BookUpdate_B333/image_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/BookUpdate_B333/image_thumb.png" width="332" height="440" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;That’s right. &lt;strong&gt;CHUCK NORRIS &lt;/strong&gt;has agreed to not only write the forward, but help coauthor the book to!&lt;/p&gt;  &lt;p&gt;Chuck and I are still working out who will own which chapters, but I’ve been able to get an advanced copy of his forward to the book.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Dear Reader,&lt;/p&gt;    &lt;p&gt;The fact you are sitting here reading this forward means that you weren’t already killed by the Russians. You have me and me alone to thank for that. &lt;/p&gt;    &lt;p&gt;&lt;/p&gt;    &lt;p&gt;&lt;/p&gt;    &lt;p&gt;&lt;/p&gt;    &lt;p&gt;&lt;/p&gt;    &lt;p&gt;In this book Chris Smith and I will teach you how to roundhouse kick concurrency issues, use an M16 to mow down mutation-related bugs, and how to divide by zero. (I’ve been doing it for years, and trust me – it’s worth it.)&lt;/p&gt;    &lt;p&gt;…&lt;/p&gt;    &lt;p&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;While I am very excited to have Chuck onboard, reading the page on &lt;a href="http://stackoverflow.com/questions/305223/jon-skeet-facts"&gt;Jon Skeet Facts&lt;/a&gt; has me worried.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Jon Skeet is immutable. If something's going to change, it's going to have to be the rest of the universe. &lt;/li&gt;    &lt;li&gt;The &lt;a href="http://en.wikipedia.org/wiki/Dining_philosophers_problem"&gt;Dining Philosophers&lt;/a&gt; wait while Jon Skeet eats. &lt;/li&gt;    &lt;li&gt;Jon Skeet can recite π. Backwards. &lt;/li&gt;    &lt;li&gt;When Jon gives a method an argument, the method loses &lt;/li&gt;    &lt;li&gt;When Jon pushes a value onto a stack, it &lt;em&gt;stays&lt;/em&gt; pushed &lt;/li&gt;    &lt;li&gt;When invoking one of Jon's callbacks, the runtime adds &amp;quot;please&amp;quot; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;It may be a tough call as for which book turns out better, but I can’t wait to see the results! In related news, Chapters 1-4 of Programming F# are available on &lt;a href="http://oreilly.com/catalog/9780596801359/"&gt;Rough Cuts&lt;/a&gt; with another couple on the way. So stay tuned!&lt;/p&gt;  &lt;p&gt;*Rumor has it that, the “creepy looking dude” on the cover of &lt;em&gt;Real World Functional Programming&lt;/em&gt; is Danish philosopher &lt;a href="http://en.wikipedia.org/wiki/S%C3%B8ren_Kierkegaard"&gt;Søren Kierkegaard&lt;/a&gt; [&lt;a href="http://www.island-of-freedom.com/tsi/biography.html"&gt;pic&lt;/a&gt;]… but does he breath fire?&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9528396" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ChrisSmithsCompletelyUniqueView/~4/Q-WwP_NhAsI" height="1" width="1"/&gt;</description><feedburner:origLink>http://blogs.msdn.com/chrsmith/archive/2009/04/01/book-update-new-coauthor.aspx</feedburner:origLink></item><item><title>Petition for Programming F#’s Book Cover!</title><link>http://feedproxy.google.com/~r/ChrisSmithsCompletelyUniqueView/~3/annRgicepzo/petition-for-programming-f-s-book-cover.aspx</link><pubDate>Mon, 02 Feb 2009 18:41:46 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9391122</guid><dc:creator>ChrSmith</dc:creator><slash:comments>21</slash:comments><comments>http://blogs.msdn.com/chrsmith/comments/9391122.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chrsmith/commentrss.aspx?PostID=9391122</wfw:commentRss><description>&lt;p&gt;You might have noticed my blogging has slowed down to a lull; never fear, this is just because I have been working&amp;#160; it is been because I have been hard at work writing I am working full steam on finishing up &lt;i&gt;&lt;a href="http://blogs.msdn.com/chrsmith/archive/2008/10/19/due-out-next-year-programming-f-by-chris-smith.aspx"&gt;Programming F#&lt;/a&gt;&lt;/i&gt;. But &lt;strong&gt;I cannot finish this book without your help&lt;/strong&gt;, read on.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The good news&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The good news is that the first three chapters of &lt;i&gt;Programming F#&lt;/i&gt; should be available online at O’Reilly’s &lt;a href="http://oreilly.com/roughcuts/"&gt;Rough Cuts&lt;/a&gt; site very soon. (Maybe this week…) Signing up for &lt;a href="http://my.safaribooksonline.com/"&gt;Safari&lt;/a&gt; will give you access to pre-release chapters of the book as well as give me feedback on how to make the book better. (Something I would greatly appreciate.)&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The bad news&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;But to be honest, as much as I’d like your feedback on early chapters of the book what I really need your help on is convincing &lt;a href="http://tim.oreilly.com/"&gt;‘the man’&lt;/a&gt; that Programming F# deserves a better cover than merely &lt;a href="http://oreilly.com/catalog/9780596521066/colophon.html"&gt;a fish&lt;/a&gt;, &lt;a href="http://oreilly.com/catalog/9780596513986/colophon.html"&gt;a rat&lt;/a&gt;, or &lt;a href="http://oreilly.com/catalog/9780596007973/colophon.html"&gt;a rabbit&lt;/a&gt;. Seriously, a rabbit?!? The linked books are all great, but having some cute and cuddly creature on the front doesn’t really inspire me to take the technology seriously.&lt;/p&gt;  &lt;p&gt;That is why when I first announced the book I mocked up a cover with a &lt;a href="http://warhammeronline.wikia.com/wiki/Squig"&gt;Squig&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/PetitionforProgrammingFsBookCover_89E7/Old%20and%20Busted%20Squigg_2.jpg"&gt;&lt;img title="The Squigg - old and busted" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="375" alt="The Squigg - old and busted" src="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/PetitionforProgrammingFsBookCover_89E7/Old%20and%20Busted%20Squigg_thumb.jpg" width="280" border="0" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;But &lt;a href="http://tim.oreilly.com/"&gt;‘the man’&lt;/a&gt; shot me down. You see, if O’Reilly is going to start having creatures more awesome than &lt;a href="http://oreilly.com/catalog/9780596153601/"&gt;a frog&lt;/a&gt; on the cover they need to enforce a few other rules:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The creature should be easily identifiable. The awesomeness of the Squig is self-evident, but few can name what it &lt;em&gt;is&lt;/em&gt; exactly. The cover on the book should be something people could recognize. &lt;/li&gt;    &lt;li&gt;The creature can’t be copyright. Most of the Squig’s awesomeness was due to the fact it was created by &lt;a href="http://www.games-workshop.com/gws/"&gt;Games Workshop&lt;/a&gt;, currently licensed to &lt;a href="http://www.warhammeronline.com/"&gt;Mythic Entertainment&lt;/a&gt;. Licensing stuff like this makes lawyers cry at night. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So I literally went back to the drawing board to think about what animal best represents F#. Something that conveys its multi-paradigm nature. Specifically, it supports imperative, object-oriented, and functional programming&lt;/p&gt;  &lt;p&gt;Then it hit me. What creature has three heads and totally kicks ass?&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;&lt;a href="http://en.wikipedia.org/wiki/Cerberus"&gt;&lt;font size="+0"&gt;Cerberus&lt;/font&gt;&lt;/a&gt;&lt;/h1&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/PetitionforProgrammingFsBookCover_89E7/800px-Cerberus-Blake_2.jpg"&gt;&lt;img title="800px-Cerberus-Blake" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="291" alt="800px-Cerberus-Blake" src="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/PetitionforProgrammingFsBookCover_89E7/800px-Cerberus-Blake_thumb.jpg" width="395" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;b&gt;Cerberus&lt;/b&gt; (&lt;a href="http://en.wikipedia.org/wiki/Greek_language"&gt;Greek&lt;/a&gt;: Κέρβερος, &lt;i&gt;Kérberos&lt;/i&gt;) is the name given to the entity which, in &lt;a href="http://en.wikipedia.org/wiki/Greek_mythology"&gt;Greek&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Roman_mythology"&gt;Roman mythology&lt;/a&gt;, is a multi-headed &lt;a href="http://en.wikipedia.org/wiki/Dog"&gt;dog&lt;/a&gt; which guards the gates of &lt;a href="http://en.wikipedia.org/wiki/Hades"&gt;Hades&lt;/a&gt;, to prevent those who have crossed the &lt;a href="http://en.wikipedia.org/wiki/River_Styx"&gt;river Styx&lt;/a&gt; from ever escaping.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now we are onto something, but to be honest having the gatekeeper for hell on the cover of my book doesn’t sit too well with me. While certainly keeping the denizens of Hades in check is a noble task, it carries along a lot of spirtual baggage. Is Cerberus evil? Or just doing his job?&amp;#160; Also, it isn’t like there are many cerberi – rather there is just the one (that I know of). &lt;/p&gt;  &lt;p&gt;So, unfortunately I need to try again. But the more I think about it I like my second choice much better. Instead of Cerberus I went with a G-D-M-F-fire-breathing-HYDRA!&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;&lt;a href="http://en.wikipedia.org/wiki/Hydra"&gt;&lt;font size="5"&gt;Hydra&lt;/font&gt;&lt;/a&gt;&lt;/h1&gt;  &lt;p&gt;You don’t F with those, you know why? Because it’s got multiple heads, and since the specifics on hydras are pretty unclear I’m going to go ahead and say that the hydra on the cover of my book &lt;strong&gt;is both undead and breathes fire&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;Yes people, a lich hydra that breaths hellfire from its multi-paradigm heads of destruction.&lt;/p&gt;  &lt;p&gt;So, I present to you, the cover of my book hopefully awesome enough to make the powers that be rethink their ‘cute and cuddly’ colophons.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/PetitionforProgrammingFsBookCover_89E7/Hydra%20Half_2.jpg"&gt;&lt;img title="Hydra Half" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="727" alt="Hydra Half" src="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/PetitionforProgrammingFsBookCover_89E7/Hydra%20Half_thumb.jpg" width="552" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Use Multi-Paradigm Programming to Devour Your Foes!&lt;/p&gt;    &lt;p&gt;“The only thing better than one fire-breathing paradigm is three!”&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Yeah, NOW we are talking. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Call to Action!&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;However, to be clear this isn’t my official book cover, but it would certainly be awesome if it was. So I need your help to convince the good folks at O’Reilly the same.&lt;/p&gt;  &lt;p&gt;So please politely send a tell to &lt;a href="http://twitter.com/laurelatoreilly"&gt;@LaurelAtOReilly&lt;/a&gt; on Twitter and let her know that a Hydra would make a much better cover than whatever the hell is on the cover of &lt;a href="http://oreilly.com/catalog/9780596100292/"&gt;Unix in a Nutshell&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;I also have a &lt;a href="http://www.cafepress.com/programmingfs"&gt;Cafe Press&lt;/a&gt; site up for T-Shirts. I haven’t received mine in the mail yet so I can’t comment on how well they will turn out.&lt;/p&gt;  &lt;p&gt;Thanks for your help and support. And remember: the ability to breath fire is always better than being furry. Always.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9391122" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ChrisSmithsCompletelyUniqueView/~4/annRgicepzo" height="1" width="1"/&gt;</description><feedburner:origLink>http://blogs.msdn.com/chrsmith/archive/2009/02/02/petition-for-programming-f-s-book-cover.aspx</feedburner:origLink></item><item><title>Deep Fried F#</title><link>http://feedproxy.google.com/~r/ChrisSmithsCompletelyUniqueView/~3/CCXcARySxSk/deep-fried-f.aspx</link><pubDate>Thu, 15 Jan 2009 23:17:35 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9321970</guid><dc:creator>ChrSmith</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/chrsmith/comments/9321970.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chrsmith/commentrss.aspx?PostID=9321970</wfw:commentRss><description>&lt;p&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" src="http://deepfriedbytes.com/images/deepfried_feedimage.png" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://deepfriedbytes.com/podcast/episode-24-chatting-about-f-with-chris-smith-and-dustin-campbell/"&gt;Episode 24: Chatting about F# with Chris Smith and Dustin Campbell&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;“Get your code on!” Being the international media sensation that I am, back at PDC &lt;a href="http://diditwith.net/"&gt;Dustin Campbell&lt;/a&gt; and I recorded a podcast for &lt;a href="http://deepfriedbytes.com/"&gt;Deep Fried Bytes&lt;/a&gt;. The podcast turned out awesome. Well, after I figured out how to talk into the mic.&lt;/p&gt;  &lt;p&gt;Some takeaways:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Both C# F# rob Peter to pay Paul.&lt;/li&gt;    &lt;li&gt;Where? Everywhere! It’s general purpose baby!&lt;/li&gt;    &lt;li&gt;I like long walks on the beach, fireside chats, and functional programming.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;A special thanks goes out to &lt;a href="http://www.mcwherter.net/blog/"&gt;Jeff&lt;/a&gt; the waterboy.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9321970" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ChrisSmithsCompletelyUniqueView/~4/CCXcARySxSk" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/chrsmith/archive/tags/A+day+in+the+life/default.aspx">A day in the life</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/Shameless+Plugs/default.aspx">Shameless Plugs</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/PDC/default.aspx">PDC</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/NEWS+FLASH/default.aspx">NEWS FLASH</category><feedburner:origLink>http://blogs.msdn.com/chrsmith/archive/2009/01/15/deep-fried-f.aspx</feedburner:origLink></item><item><title>New Years resolutions v2.0.0.9</title><link>http://feedproxy.google.com/~r/ChrisSmithsCompletelyUniqueView/~3/cGTb2AHzTbk/new-years-resolutions-v2-0-0-9.aspx</link><pubDate>Thu, 15 Jan 2009 21:56:03 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9321642</guid><dc:creator>ChrSmith</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/chrsmith/comments/9321642.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chrsmith/commentrss.aspx?PostID=9321642</wfw:commentRss><description>&lt;p&gt;So I was tagged by my new homie &lt;a href="http://www.codinggeekette.com/2009/01/coding-geekettes-goals-for-2009.aspx"&gt;Sarah Dutkiewicz&lt;/a&gt; AKA &lt;a href="http://www.codinggeekette.com/"&gt;Coding Geekette&lt;/a&gt; about blogging my goals for 2009. I was on the fence at first about whether or not to share such private information with the world. But after seeing &lt;a href="http://jrwren.wrenfam.com/blog/"&gt;Jay Wren&lt;/a&gt; admit to being a “Law and Order addict”, I couldn’t embarrass myself too much.&lt;/p&gt;  &lt;p&gt;First let me provide a disclaimer. These goals certainly make me sound like some sort of ultra-driven alpha-male type person. But rest assured that I’m just as lazy and apathetic about life as you are, it just happens that 2009 will be a busy year.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Graduate with my Masters degree&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;I have been taking classes at the University of Washington &lt;a href="http://pmp.cs.washington.edu/"&gt;Professional Masters Program&lt;/a&gt; for about two years now and hopefully I will graduate this spring. Getting my Computer Science Masters degree is very important for backing up my reputation as a true &lt;a href="http://www.cs.purdue.edu/homes/anavabi/mp3/MC%20Plus+%20-%20Chip%20Hop%20-%20Chip%20Hop%20Nerd.mp3"&gt;CS Gangsta&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/NewYearsresolutionsv2.0.0.9_B835/clip_image002_2.jpg"&gt;&lt;img title="Alma matter version 2.0" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="164" alt="Alma matter version 2.0" src="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/NewYearsresolutionsv2.0.0.9_B835/clip_image002_thumb.jpg" width="244" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Of course it will be hard to divide my time between ‘actual class’ and just watching the &lt;a href="http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/"&gt;lectures&lt;/a&gt; for &lt;i&gt;Structure and Interpertation of Computer Programs&lt;/i&gt; by Hal Abelson and Gerald Sussman. Who doesn’t want to learn Lisp?&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Finish writing &lt;i&gt;Programming F#&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/chrsmith/archive/2008/10/19/due-out-next-year-programming-f-by-chris-smith.aspx"&gt;Programming F#&lt;/a&gt; is coming along, but not without its tribulations. I’m trying to convince &lt;a href="http://www.oreillynet.com/pub/au/468"&gt;John Osborn&lt;/a&gt; that my book should, in fact, have a Squigg on the cover. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/DueoutNextYearProgrammingFbyChrisSmith_B363/Squig_Oreilly_2.jpg"&gt;&lt;img title="Buy my book!" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="287" alt="Buy my book!" src="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/NewYearsresolutionsv2.0.0.9_B835/clip_image004_b22df137-5083-4480-a00b-d47f0abfc2eb.jpg" width="210" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I’m going to try to get the first few chapters on O’Reilly’s &lt;a href="http://oreilly.com/roughcuts/"&gt;Rough Cuts&lt;/a&gt; site by the end of the month. So stay tuned!&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;&lt;s&gt;Ship F# in Visual Studio 2010&lt;/s&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Kick ass and take names at work&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;Working as a tester at Microsoft has a few perks. Not only do I get free soda but I actually get paid to complain and criticize our software. (It is so much fun people do that already for free!) Anyways, it is my personal mission to see F# ship in Visual Studio 2010 and be the most awesome feature in the box. So in 2009 my goal is to do just that.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Drop the dead weight&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;Who doesn’t have ‘lose some weight’ as part of their New Year’s resolutions? To mix things up, rather than simply going to the gym, I’m going to see how much weight I lose by quitting Taco Bell cold turkey. New rule, no more delicious nacho cheese chalupas with chicken for a whole year. Can I do it? Only time will tell…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/NewYearsresolutionsv2.0.0.9_B835/clip_image006_2.jpg"&gt;&lt;img title="Me running a 10K" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="244" alt="Me running a 10K" src="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/NewYearsresolutionsv2.0.0.9_B835/clip_image006_thumb.jpg" width="163" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;And my last, and perhaps most important, goal is:&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Enjoy 2009 more than 2008&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;Truth be told 2008 had a lot of drama-lama-ding-dong for me and I’m looking to being drama-free for 2009. Go skiing more, spend more time with friends and family. I want to cultivate and encourage that which is awesome. If you have any suggestions let me know.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;In the spirit of transforming blogging into modern chain letters, I’ll tag:&lt;/p&gt;  &lt;p&gt;· &lt;a href="http://lorgonblog.spaces.live.com/"&gt;’Dr.’ Brian McNamara&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;· &lt;a href="http://blogs.msdn.com/kirillosenkov/default.aspx"&gt;Kirill ‘C# genius’ Osenkov&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;· &lt;a href="http://www.diditwith.net/"&gt;Dustin ‘kind of a big deal’ Campbell&lt;/a&gt;*&lt;/p&gt;  &lt;p&gt;*Despite the nickname, Dustin is not actually a big deal. Maybe if he blogged more often…&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9321642" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ChrisSmithsCompletelyUniqueView/~4/cGTb2AHzTbk" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/chrsmith/archive/tags/The+future/default.aspx">The future</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/me+too/default.aspx">me too</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/Personal/default.aspx">Personal</category><feedburner:origLink>http://blogs.msdn.com/chrsmith/archive/2009/01/15/new-years-resolutions-v2-0-0-9.aspx</feedburner:origLink></item><item><title>Speech Recognition is gun and easy!</title><link>http://feedproxy.google.com/~r/ChrisSmithsCompletelyUniqueView/~3/6hXA38aeYNo/speech-recognition-is-gun-and-easy.aspx</link><pubDate>Wed, 31 Dec 2008 07:03:55 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9258172</guid><dc:creator>ChrSmith</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/chrsmith/comments/9258172.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chrsmith/commentrss.aspx?PostID=9258172</wfw:commentRss><description>&lt;p&gt;Evidently Microsoft ninjaed a new assembly into the .NET framework with the 3.0 release called System.Speech.dll. If adding speech recognition or speech synthesis to your applications sounds like fun, read on.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Step 1: Train your computer&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The first step for meaningful speech recognition is to tell your computer who is in charge. Open up the Control Panel, navigate to Ease of Access, Speech Recognition options, then select Training. The process of training will take about 10 minutes and is pretty tedious, but the results are well worth it.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/SpeechRecognitionisgunandeasy_1444E/image_2.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="457" alt="image" src="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/SpeechRecognitionisgunandeasy_1444E/image_thumb.png" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; &lt;strong&gt;Write some F# code&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;This is the easy part.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;#light

open &lt;/span&gt;System
&lt;span style="color: blue"&gt;open &lt;/span&gt;System.Speech.Recognition

&lt;span style="color: blue"&gt;let &lt;/span&gt;sp = &lt;span style="color: blue"&gt;new &lt;/span&gt;SpeechRecognitionEngine()
&lt;span style="color: blue"&gt;let &lt;/span&gt;defaultDictationGrammar = &lt;span style="color: blue"&gt;new &lt;/span&gt;DictationGrammar()

defaultDictationGrammar.Name &amp;lt;- &lt;span style="color: maroon"&gt;&amp;quot;Default Dictation&amp;quot;
&lt;/span&gt;defaultDictationGrammar.Enabled &amp;lt;- &lt;span style="color: blue"&gt;true

&lt;/span&gt;sp.LoadGrammar(defaultDictationGrammar)
sp.SetInputToDefaultAudioDevice()

sp.RecognizeAsync(RecognizeMode.Multiple)

sp.SpeechRecognized.Add(&lt;span style="color: blue"&gt;fun &lt;/span&gt;args &lt;span style="color: blue"&gt;-&amp;gt; &lt;/span&gt;printfn &lt;span style="color: maroon"&gt;&amp;quot;Recognized [%f] '%s'&amp;quot; &lt;/span&gt;args.Result.Confidence args.Result.Text)

printfn (&lt;span style="color: maroon"&gt;&amp;quot;(Just start talking. Press any key to quit.)&amp;quot;&lt;/span&gt;)
Console.ReadKey(&lt;span style="color: blue"&gt;true&lt;/span&gt;) |&amp;gt; ignore&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Profit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Early results look promising, although it doesn't handle early 90's rap very well...&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/SpeechRecognitionisgunandeasy_1444E/image_4.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="343" alt="image" src="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/SpeechRecognitionisgunandeasy_1444E/image_thumb_1.png" width="678" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/SpeechRecognitionisgunandeasy_1444E/image_8.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="288" alt="image" src="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/SpeechRecognitionisgunandeasy_1444E/image_thumb_3.png" width="666" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9258172" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ChrisSmithsCompletelyUniqueView/~4/6hXA38aeYNo" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/chrsmith/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/Snippets/default.aspx">Snippets</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/Speech/default.aspx">Speech</category><feedburner:origLink>http://blogs.msdn.com/chrsmith/archive/2008/12/30/speech-recognition-is-gun-and-easy.aspx</feedburner:origLink></item><item><title>F# No Longer Vaporware</title><link>http://feedproxy.google.com/~r/ChrisSmithsCompletelyUniqueView/~3/G-fFdc_mwa8/f-no-longer-vaporware.aspx</link><pubDate>Wed, 10 Dec 2008 23:05:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9193045</guid><dc:creator>ChrSmith</dc:creator><slash:comments>20</slash:comments><comments>http://blogs.msdn.com/chrsmith/comments/9193045.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chrsmith/commentrss.aspx?PostID=9193045</wfw:commentRss><description>&lt;P&gt;REDMOND, WA - Sadly, after nearly four years of stringing developers along with Microsoft's longest touted non-product, F# was accidentally checked into the &lt;A href="http://www.microsoft.com/visualstudio/2010/overview.mspx" mce_href="http://www.microsoft.com/visualstudio/2010/overview.mspx"&gt;Visual Studio 2010&lt;/A&gt; source tree Microsoft sources report. This mistake killed what would have been one of Microsoft's most popular &lt;A href="http://en.wikipedia.org/wiki/Vaporware" mce_href="http://en.wikipedia.org/wiki/Vaporware"&gt;vaporware&lt;/A&gt; project by giving it an actual release date. &lt;/P&gt;
&lt;P&gt;The checkin was made by an intern, who was simply experimenting with his new Visual Studio &lt;A href="http://msdn.microsoft.com/en-us/tfs2008/default.aspx" mce_href="http://msdn.microsoft.com/en-us/tfs2008/default.aspx"&gt;Team Foundation Server&lt;/A&gt; enlistment. As a result of the checkin the F# compiler and project system will eventually ship with the next release of Visual Studio, Microsoft's premier development tool.&lt;/P&gt;
&lt;P&gt;When asked about the event, senior researcher and language creator &lt;A href="http://blogs.msdn.com/dsyme/" mce_href="http://blogs.msdn.com/dsyme/"&gt;Don Syme&lt;/A&gt; lamented:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;“It’s crazy. I mean, what do we do now - we can’t get it out. I was just working on F# as a way of getting out of all of those boring academic conferences. A way of looking busy for my boss. Then I come back from lunch Monday and the sucker was checked-in. This is a total ******* catastrophe.&lt;/P&gt;
&lt;P&gt;I really don’t understand this place, you think we would have learned our lesson. You know those .NET Generics – same thing there too. Once Microsoft, always Microsoft – this place never changes.”&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;In fact, the entire F# team was shocked to hear the news. Developer &lt;A href="http://lorgonblog.spaces.live.com/" mce_href="http://lorgonblog.spaces.live.com/"&gt;Brian McNamara&lt;/A&gt; was quoted, “I didn’t sign on to work 80-hours a week only to have my code released to the world. This sucks, you mean to tell me that now people are going to actually use F#?” &lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/FNoLongerVaporware_D373/clip_image002_2.jpg" mce_href="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/FNoLongerVaporware_D373/clip_image002_2.jpg"&gt;&lt;IMG title=clip_image002 style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; DISPLAY: inline; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=244 alt=clip_image002 src="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/FNoLongerVaporware_D373/clip_image002_thumb.jpg" width=223 border=0 mce_src="http://blogs.msdn.com/blogfiles/chrsmith/WindowsLiveWriter/FNoLongerVaporware_D373/clip_image002_thumb.jpg"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/lukeh/" mce_href="http://blogs.msdn.com/lukeh/"&gt;Luke Hoban&lt;/A&gt;, program manager for the project was also troubled:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;“Giving demos with this functional programming stuff is one thing; but an actual F# product is definitely another. If we ship it people will actually expect F# to be usable. You know, solve real world problems and stuff. This changes our whole strategy. When we were just demoing all we had to worry about was style. Substance on the other hand requires hard work.”&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;According to Hoban, most vaporware projects at Microsoft get terminated long before they build up much hype. F# was one of the company's most successful vaporware projects until last Monday. "We were able to keep up the illusion of shipping for so long by putting out CTP and beta releases. We probably could have probably shipped those things for another few years before people caught on that we never actually intended to ship F# in an officially supported release."&lt;/P&gt;
&lt;P&gt;Below is an image the F# team was hoping to only mock up using &lt;A href="http://en.wikipedia.org/wiki/Power_point" mce_href="http://en.wikipedia.org/wiki/Power_point"&gt;PowerPoint&lt;/A&gt; and &lt;A href="http://en.wikipedia.org/wiki/Microsoft_Paint" mce_href="http://en.wikipedia.org/wiki/Microsoft_Paint"&gt;MSPaint&lt;/A&gt;. But after the source code accident, the screen shot is from an actual build of Visual Studio 2010. &lt;/P&gt;
&lt;P&gt;&lt;A href="file:///C:/Users/chrsmith/AppData/Roaming/Windows%20Live%20Writer/PostSupportingFiles/2b92c05d-a215-41c5-b23d-5a41ed748608/clip_image001[4].jpg" mce_href="file:///C:\Users\chrsmith\AppData\Roaming\Windows%20Live%20Writer\PostSupportingFiles\2b92c05d-a215-41c5-b23d-5a41ed748608\clip_image001%5b4%5d.jpg"&gt;&lt;B&gt;&lt;/B&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;IMG title="F# in Dev10" alt="F# in Dev10" src="http://blogs.msdn.com/photos/chrsmith/images/9194443/original.aspx" mce_src="http://blogs.msdn.com/photos/chrsmith/images/9194443/original.aspx"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Currently the F# team in Redmond, Washington is scrambling to recover. Developer &lt;A href="http://blogs.msdn.com/jomo_fisher/" mce_href="http://blogs.msdn.com/jomo_fisher/"&gt;Jomo Fisher&lt;/A&gt; set up an emergency meeting with Senior Vice President &lt;A href="http://blogs.msdn.com/somasegar/" mce_href="http://blogs.msdn.com/somasegar/"&gt;S. Somasegar&lt;/A&gt; to discuss the potential ramifications of introducing .NET developers to functional programming. &lt;/P&gt;
&lt;P&gt;The impact of this news is slowly being felt across the broader .NET developer community as well. &lt;A href="http://weblogs.asp.net/podwysocki/" mce_href="http://weblogs.asp.net/podwysocki/"&gt;Matthew Podwysoki&lt;/A&gt;, an avid F# blogger, was frustrated to hear the news:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;“The bleeding edge of software has always been vaporware. Actually shipping F# in a box is so banal. How else am I supposed to impress people if not by saying that I know F#, a space-age programming language that you’ve never heard of. &lt;/P&gt;
&lt;P&gt;If it becomes mainstream then I’ll probably have to learn something else. I mean, what’s next? People writing books for &lt;A href="http://oreilly.com/" mce_href="http://oreilly.com/"&gt;O'Reilly&lt;/A&gt; and putting &lt;A href="http://blogs.msdn.com/chrsmith/archive/2008/10/19/due-out-next-year-programming-f-by-chris-smith.aspx" mce_href="http://blogs.msdn.com/chrsmith/archive/2008/10/19/due-out-next-year-programming-f-by-chris-smith.aspx"&gt;flesh-eating demons&lt;/A&gt; on the cover? Come on.”&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Not everybody reacted as emotionally to the news. Program manager &lt;A href="http://diditwith.net/default.aspx" mce_href="http://diditwith.net/default.aspx"&gt;Dustin Campbell&lt;/A&gt; tried to give perspective:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;“Sometimes even the most promising projects ship. It happens. It is just part of software development. Either through good management, realistic schedules, or solid programmers some projects actually complete on time. &lt;/P&gt;
&lt;P&gt;You just need to hope your next project will turn out better. If I were those F# guys, I’d be twice as lackadaisical in the planning of version 2.0.”&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;It may take weeks or even months for the team to cope with the unexpected realization that F# will eventually become a reality in Visual Studio 2010. In the mean time, you can protect yourself from productivity improvements induced by the language by avoiding any future Beta or CTP releases of Visual Studio 2010.&lt;/P&gt;
&lt;P&gt;When Visual Studio 2010 is released, your best and only defense is to be prepared. Microsoft has began recommending that interested developers watch &lt;A href="http://blogs.msdn.com/lucabol/" mce_href="http://blogs.msdn.com/lucabol/"&gt;Luca Bolognese’s&lt;/A&gt; presentation titled &lt;A href="http://channel9.msdn.com/pdc2008/TL11/" mce_href="http://channel9.msdn.com/pdc2008/TL11/"&gt;An Introduction to Microsoft F#&lt;/A&gt;. &lt;/P&gt;
&lt;P&gt;Check back here for more information on this story as it develops.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9193045" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ChrisSmithsCompletelyUniqueView/~4/G-fFdc_mwa8" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/chrsmith/archive/tags/A+day+in+the+life/default.aspx">A day in the life</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/The+future/default.aspx">The future</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/NEWS+FLASH/default.aspx">NEWS FLASH</category><feedburner:origLink>http://blogs.msdn.com/chrsmith/archive/2008/12/10/f-no-longer-vaporware.aspx</feedburner:origLink></item><item><title>F# Zen - Array slices</title><link>http://feedproxy.google.com/~r/ChrisSmithsCompletelyUniqueView/~3/fW8NC7fxI4A/f-zen-array-slices.aspx</link><pubDate>Tue, 09 Dec 2008 19:37:29 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9187737</guid><dc:creator>ChrSmith</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/chrsmith/comments/9187737.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chrsmith/commentrss.aspx?PostID=9187737</wfw:commentRss><description>&lt;p&gt;Sorry for not being as regular with blogging, I've been sick and working hard on something pretty exciting. Don will post an announcement sooner or later.&lt;/p&gt;  &lt;p&gt;Anyways, did you know that in F# you can easily take out a chunk of an array using an Array Slice? This is a simple syntax for selecting a subset of an array, which creates a new array copying the values. This slice syntax also works for 2D arrays as well in much the same way. (E.g., daysOfYear.[*, ..5])&lt;/p&gt;  &lt;p&gt;Here are some simple examples:&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;open &lt;/span&gt;System
&lt;span style="color: blue"&gt;let &lt;/span&gt;daysOfWeek = Enum.GetNames( typeof&amp;lt;DayOfWeek&amp;gt; );;

&lt;span style="color: green"&gt;// Standard array slice, elements 2 through 4
&lt;/span&gt;daysOfWeek.[2..4];;

&lt;span style="color: green"&gt;// Just specify lower bound, elements 4 to the end
&lt;/span&gt;daysOfWeek.[4..];;

&lt;span style="color: green"&gt;// Just specify an upper bound, elements 0 to 2
&lt;/span&gt;daysOfWeek.[..2];;

&lt;span style="color: green"&gt;// Specify no bounds, get all elements (clones the array)
&lt;/span&gt;daysOfWeek.[*];;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9187737" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ChrisSmithsCompletelyUniqueView/~4/fW8NC7fxI4A" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/chrsmith/archive/tags/F_2300_+Zen/default.aspx">F# Zen</category><feedburner:origLink>http://blogs.msdn.com/chrsmith/archive/2008/12/09/f-zen-array-slices.aspx</feedburner:origLink></item><item><title>F# Zen - ROT13</title><link>http://feedproxy.google.com/~r/ChrisSmithsCompletelyUniqueView/~3/5056Qf4c87o/f-zen-rot13.aspx</link><pubDate>Fri, 07 Nov 2008 22:33:24 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9053195</guid><dc:creator>ChrSmith</dc:creator><slash:comments>12</slash:comments><comments>http://blogs.msdn.com/chrsmith/comments/9053195.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chrsmith/commentrss.aspx?PostID=9053195</wfw:commentRss><description>&lt;p&gt;Below is a primitive implementation of &lt;a href="http://en.wikipedia.org/wiki/ROT13"&gt;ROT13&lt;/a&gt; / &lt;a href="http://en.wikipedia.org/wiki/Caesar_cipher"&gt;Ceasar Cipher&lt;/a&gt; in F#. In short it is a simple encryption algorithm that works by 'shifting' each letter 13 places. So an 'a' becomes an 'n', a 'b' becomes an 'o', and so on. To decrypt the text you simply move 13 places in reverse. &lt;/p&gt;  &lt;p&gt;We can do this in F# easily using function composition. Given a string, which is also a sequence of characters, we pass it to Array.of_seq so we have an array of characters. This will enable us to replace each character with its encrypted version. Next we map each character to our encryption function, which I'll go over next. Finally, we take our array of encrypted characters and return a new string.&lt;/p&gt;  &lt;p&gt;To actually do the encryption, we will compose three functions together. int, will convert the character to its integer representation. &amp;quot;(+) 13&amp;quot; is a curried version of the (+) function, so it adds 13 to its argument. And then we compose that with the char function, which will convert the integer result to a character.&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;#light

&lt;/span&gt;&lt;span style="color: green"&gt;(**
 * ROT13 in F#
 * 
 * 1. Convert the sequence of chars (string) to an array of chars
 * 2. For each character do the following:
 *    - Convert the character to an integer
 *    - Add 13 to the integer value of the character (by currying (+))
 *    - Convert the integer to a character
 * 3. Create a new string based off the encrypted characters
 *)
 
&lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;EncryptText (text : string) = 
    text
    |&amp;gt; Array.of_seq
    |&amp;gt; Array.map (int &amp;gt;&amp;gt; ((+) 13) &amp;gt;&amp;gt; char)
    |&amp;gt; (&lt;span style="color: blue"&gt;fun &lt;/span&gt;chars &lt;span style="color: blue"&gt;-&amp;gt; new &lt;/span&gt;string(chars))

&lt;span style="color: blue"&gt;let &lt;/span&gt;DecryptText (text : string) = 
    text
    |&amp;gt; Array.of_seq
    |&amp;gt; Array.map (int &amp;gt;&amp;gt; ((+) -13) &amp;gt;&amp;gt; char)
    |&amp;gt; (&lt;span style="color: blue"&gt;fun &lt;/span&gt;chars &lt;span style="color: blue"&gt;-&amp;gt; new &lt;/span&gt;string(chars))

&lt;span style="color: blue"&gt;let &lt;/span&gt;Test message =
    &lt;span style="color: blue"&gt;let &lt;/span&gt;encrypted = EncryptText message
    &lt;span style="color: blue"&gt;let &lt;/span&gt;decrypted = DecryptText encrypted

    printfn &lt;span style="color: maroon"&gt;&amp;quot;Original Message  = %s&amp;quot; &lt;/span&gt;message
    printfn &lt;span style="color: maroon"&gt;&amp;quot;Encrypted Message = %s&amp;quot; &lt;/span&gt;encrypted
    printfn &lt;span style="color: maroon"&gt;&amp;quot;Decrypted Message = %s&amp;quot; &lt;/span&gt;decrypted
    
Test &lt;span style="color: maroon"&gt;&amp;quot;The quick fox jumped over the lazy dog&amp;quot;
&lt;/span&gt;&lt;/pre&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9053195" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ChrisSmithsCompletelyUniqueView/~4/5056Qf4c87o" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/chrsmith/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/F_2300_+Zen/default.aspx">F# Zen</category><feedburner:origLink>http://blogs.msdn.com/chrsmith/archive/2008/11/07/f-zen-rot13.aspx</feedburner:origLink></item><item><title>F# Elevator Pitch</title><link>http://feedproxy.google.com/~r/ChrisSmithsCompletelyUniqueView/~3/OoLN0c8phf4/f-elevator-pitch.aspx</link><pubDate>Sat, 01 Nov 2008 16:24:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9028289</guid><dc:creator>ChrSmith</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/chrsmith/comments/9028289.aspx</comments><wfw:commentRss>http://blogs.msdn.com/chrsmith/commentrss.aspx?PostID=9028289</wfw:commentRss><description>&lt;P&gt;At the PDC I spent about eight hours a day for a full week answering the same question again and again: “What is F# and why should I use it.” While I would love to give a long and nuanced answer to this, in order to achieve a high throughput you need to resort to using the &lt;A class="" title="Elevator Pitch" href="http://en.wikipedia.org/wiki/Elevator_pitch" mce_href="http://en.wikipedia.org/wiki/Elevator_pitch"&gt;Elevator Pitch &lt;/A&gt;style.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;The Pitch&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;So your boss comes to you and says your company is about to go bankrupt unless you write some application that will save the day. Having been told this time and time again you fire up Visual Studio and get to work. &lt;BR&gt;The data access layer is trivial; you have code generators and UI tools to help out. The presentation layer is easy too – you have WYSIWYG designers. All you need to do them is wire these things together, which is straightforward in an object-oriented language. So from the get-go building the framework for your application is easy. &lt;/P&gt;
&lt;P&gt;Your boss sees that your project is ‘mostly done’ and breathes a sigh of relief. He then starts stressing out about other things. But in reality, now is the time that the hard programming work begins. Conceptually you’re just putting the meat in your application – some business logic, implementing an algorithm, transforming some data. General computation. But this is really painful in C#.&lt;/P&gt;
&lt;P&gt;Think about design patterns. They are actually really simple concepts, but require a complex web of types and interfaces to implement. This is because at heart everything in an OO language must be a class, so if you want to represent something simpler than that – a function, an algorithm, a piece of data – you have to build some OO hierarchy on top of it. &lt;/P&gt;
&lt;P&gt;You could waste your time writing a lot of boiler plate code that has nothing to do with solving your problem, but fortunately there is a better way.&lt;/P&gt;
&lt;P&gt;Instead of burning a week or two writing your functions and algorithms in terms of classes, you write your code in F#. F# is a new .NET programming language that approaches programming from an entirely different perspective. Abstracting algorithms, numeric computation, data analysis and exploration – all of these things are just easier in F#. Because that’s what the language is built to do.&lt;/P&gt;
&lt;P&gt;So you write some part of your application in F# and shave weeks off your development time. And, because of the interoperability of the CLR, you can use it directly with your C# code and your boss/team is none the wiser. Your company is saved and you don’t have to work this weekend.&lt;/P&gt;
&lt;P&gt;F# will make you extremely productive at algorithmic-level development (AKA &lt;A class="" title="programming in the small" href="http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!511.entry" mce_href="http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!511.entry"&gt;programming in the small&lt;/A&gt;). So you can use&amp;nbsp;F# where&amp;nbsp;it makes sense and C# for everything else. F# is powerful new language for your tool belt.&lt;BR&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9028289" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/ChrisSmithsCompletelyUniqueView/~4/OoLN0c8phf4" height="1" width="1"/&gt;</description><category domain="http://blogs.msdn.com/chrsmith/archive/tags/F_2300_/default.aspx">F#</category><category domain="http://blogs.msdn.com/chrsmith/archive/tags/F_2300_+Zen/default.aspx">F# Zen</category><feedburner:origLink>http://blogs.msdn.com/chrsmith/archive/2008/11/01/f-elevator-pitch.aspx</feedburner:origLink></item></channel></rss>
