<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">LukeH's WebLog</title><subtitle type="html" /><id>http://blogs.msdn.com/lukeh/atom.xml</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/lukeh/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/lukeh/atom.xml" /><generator uri="http://communityserver.org" version="2.1.61025.2">Community Server</generator><updated>2007-06-07T10:42:27Z</updated><entry><title>ICFP Programming Contest 2009</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/lukeh/archive/2009/06/26/icfp-programming-contest-2009.aspx" /><id>http://blogs.msdn.com/lukeh/archive/2009/06/26/icfp-programming-contest-2009.aspx</id><published>2009-06-26T06:56:00Z</published><updated>2009-06-26T06:56:00Z</updated><content type="html">&lt;P&gt;This year’s &lt;A href="http://icfpcontest.org/" mce_href="http://icfpcontest.org"&gt;ICFP Programming Contest&lt;/A&gt; starts today.&amp;nbsp; We’ve got a team participating, any other F# teams out there?&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Last year, I posted an &lt;A href="http://blogs.msdn.com/lukeh/archive/2008/07/10/icfp-programming-contest.aspx" mce_href="http://blogs.msdn.com/lukeh/archive/2008/07/10/icfp-programming-contest.aspx"&gt;F# implementation of the 2006 ICFP contest problem&lt;/A&gt;, which was an amazing and complex set of puzzles inside a custom virtual machine.&amp;nbsp;&amp;nbsp; Here’s a Silverlight version of that virtual machine, implemented on top of the &lt;A href="http://blogs.msdn.com/lukeh/archive/2009/06/26/f-in-silverlight.aspx" mce_href="http://blogs.msdn.com/lukeh/archive/2009/06/26/f-in-silverlight.aspx"&gt;Console sample&lt;/A&gt; I posted yesterday.&lt;/P&gt;
&lt;H2&gt;Silverlight UM – ICFP 2006&lt;/H2&gt;
&lt;P&gt;See &lt;A title=http://boundvariable.org/ href="http://boundvariable.org/" mce_href="http://boundvariable.org/"&gt;http://boundvariable.org/&lt;/A&gt; and my &lt;A href="http://blogs.msdn.com/lukeh/archive/2008/07/10/icfp-programming-contest.aspx" mce_href="http://blogs.msdn.com/lukeh/archive/2008/07/10/icfp-programming-contest.aspx"&gt;previous post&lt;/A&gt; for details of what’s running in this console.&lt;/P&gt;
&lt;P&gt;[Note: Copy/Paste is supported on some browsers, but not when embedded in the blog post.&amp;nbsp; Use &lt;A href="http://lukeh.cloudapp.net/UMTestPage.aspx" mce_href="http://lukeh.cloudapp.net/UMTestPage.aspx"&gt;this page&lt;/A&gt; instead.]&lt;/P&gt;&lt;EMBED height=400 type=application/x-silverlight-2 width=600 src=http://lukeh.cloudapp.net/ClientBin/UM.xap background="white" onerror="javascript:alert('error');" source="http://lukeh.cloudapp.net/ClientBin/UM.xap" mce_src="http://lukeh.cloudapp.net/ClientBin/UM.xap" data="data:application/x-silverlight,"&gt;&lt;/EMBED&gt; 
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/EMBED&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: green"&gt; /// Start the UM running on a background thread.  
 /// The input and output functions will be called on the 
 /// background thread, and block the execution of the UM
 &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;static member &lt;/SPAN&gt;Launch(binaryUri : Uri, input : Stream, output : Stream) = 
     async { 
         &lt;SPAN style="COLOR: blue"&gt;try 
             let &lt;/SPAN&gt;writer = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;System.IO.StreamWriter(output, AutoFlush=&lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;)
             &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;reader = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;System.IO.StreamReader(input)
             &lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;writer.WriteLine(&lt;SPAN style="COLOR: maroon"&gt;"Press &amp;lt;enter&amp;gt; to begin.  Note: Will download a large UMIX image."&lt;/SPAN&gt;)
             &lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;reader.ReadLine() |&amp;gt; ignore
             &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;request = System.Net.WebRequest.Create(binaryUri)
             &lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;writer.WriteLine(binaryUri)
             &lt;SPAN style="COLOR: blue"&gt;let! &lt;/SPAN&gt;response = request.AsyncGetResponse()
             &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;stream = response.GetResponseStream()
             &lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;writer.WriteLine(&lt;SPAN style="COLOR: maroon"&gt;"Downloading..."&lt;/SPAN&gt;)
             &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;progress(percent) = writer.WriteLine(&lt;SPAN style="COLOR: maroon"&gt;"Downloaded: "&lt;/SPAN&gt;+percent.ToString()+&lt;SPAN style="COLOR: maroon"&gt;"%"&lt;/SPAN&gt;)
             &lt;SPAN style="COLOR: blue"&gt;let! &lt;/SPAN&gt;bytes = asyncReadAllBytesFromStreamWithProgress (stream, int response.ContentLength, progress)
&lt;SPAN style="COLOR: blue"&gt;             do &lt;/SPAN&gt;writer.WriteLine(&lt;SPAN style="COLOR: maroon"&gt;"Booting..."&lt;/SPAN&gt;)&lt;BR&gt;             &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;ee = UM(bytes, Func&amp;lt;int&amp;gt;(input.ReadByte), Action&amp;lt;byte&amp;gt;(output.WriteByte))
             ee.Run()
         &lt;SPAN style="COLOR: blue"&gt;with 
         &lt;/SPAN&gt;| e &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;System.Diagnostics.Debug.WriteLine(&lt;SPAN style="COLOR: maroon"&gt;"UM failed with {0}"&lt;/SPAN&gt;, e)
     } |&amp;gt; Async.Start
     &lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;H3&gt;F# Async in Silverlight&lt;/H3&gt;
&lt;P&gt;In Silverlight, the APIs for synchronous I/O have been removed, which forces developers to do the ‘right thing’ and make async calls for long-running I/O operations, thus (hopefully) keeping the UI responsive.&amp;nbsp; This makes F# a really nice implementation language for Silverlight applications, using F#’s async workflows.&amp;nbsp; In the code above, an asynchronous workflow describes the flow of control of launching the UM.&amp;nbsp; At the two points of long running network connections, async calls are made with “let!”, so that the UI thread is not blocked and the application remains responsive.&amp;nbsp; This ultimately hides a lot of complexity that would be added in chaining these asynchronous operations together in a standard .NET approach to this.&lt;/P&gt;
&lt;P&gt;Note also that the code above calls a helper function “asyncReadAllBytesFromStreamWithProgress”, which shows how async code in F# can be nicely factored using the same sort of “extract method” factoring you are used to in synchronous programming.&amp;nbsp; The implementation of this helper also shows that async calls with ‘let!’ can be placed inside ‘for’ and ‘while’ loops.&amp;nbsp; Chances are you don’t even want to try doing that with standard Begin/End calls!&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;let internal &lt;/SPAN&gt;asyncReadAllBytesFromStreamWithProgress(stream:Stream, length:int, progress:int-&amp;gt;unit) = 
    async {
        &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;offset = ref 0
        &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;count = ref length
        &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;buffer = Array.zeroCreate&amp;lt;byte&amp;gt; !count
        &lt;SPAN style="COLOR: blue"&gt;while &lt;/SPAN&gt;!count &amp;gt; 0 &lt;SPAN style="COLOR: blue"&gt;do
            let! &lt;/SPAN&gt;bytesRead = stream.AsyncRead(buffer, !offset, (min 524288 !count))
            &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;bytesRead = 0 &lt;SPAN style="COLOR: blue"&gt;then &lt;/SPAN&gt;raise (&lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;EndOfStreamException(&lt;SPAN style="COLOR: maroon"&gt;"Read beyond the EOF"&lt;/SPAN&gt;))
            &lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;offset := !offset + bytesRead
            &lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;count := !count - bytesRead
            progress(100 * !offset / length)
        &lt;SPAN style="COLOR: blue"&gt;return &lt;/SPAN&gt;buffer
    }&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;H3&gt;Consuming F# from C#+XAML&lt;/H3&gt;
&lt;P&gt;The majority of this app is written in F# – the console control is authored in F# and the application logic is in F#.&amp;nbsp; Here is the C# and XAML that ties it together:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;UserControl &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;xmlns&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;my&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="clr-namespace:System.Windows.Controls;assembly=SilverlightConsole"  &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;x&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Class&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="UM.Page"
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;xmlns&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;xmlns&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;x&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="http://schemas.microsoft.com/winfx/2006/xaml" 
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Width&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="600" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Height&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="400"&amp;gt;
    &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Grid &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;x&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="LayoutRoot" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Background&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="White"&amp;gt;
        &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;my&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;SilverlightConsole &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;x&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Name&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="console" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Width&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="600" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Height&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="400" 
                               &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;FontFamily&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="Courier New" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;FontSize&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="13" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;FontWeight&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="Bold" 
                               &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Foreground&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="GreenYellow" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Background&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="Black" &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;Text&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;="" /&amp;gt;
    &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;Grid&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;
&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;UserControl&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;public partial class &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Page &lt;/SPAN&gt;: &lt;SPAN style="COLOR: #2b91af"&gt;UserControl &lt;/SPAN&gt;{
    &lt;SPAN style="COLOR: blue"&gt;public &lt;/SPAN&gt;Page() {
        InitializeComponent();

        &lt;SPAN style="COLOR: #2b91af"&gt;Uri &lt;/SPAN&gt;curPage = System.Windows.&lt;SPAN style="COLOR: #2b91af"&gt;Application&lt;/SPAN&gt;.Current.Host.Source;
        &lt;SPAN style="COLOR: #2b91af"&gt;UriBuilder &lt;/SPAN&gt;builder = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;UriBuilder&lt;/SPAN&gt;(curPage.Scheme, curPage.Host, curPage.Port, &lt;SPAN style="COLOR: #a31515"&gt;"umix.dll"&lt;/SPAN&gt;);
        &lt;SPAN style="COLOR: #2b91af"&gt;ICFP&lt;/SPAN&gt;.&lt;SPAN style="COLOR: #2b91af"&gt;UM&lt;/SPAN&gt;.Launch(builder.Uri, console.InputStream, console.OutputStream);
    }
}&lt;/PRE&gt;
&lt;H2&gt;Summary&lt;/H2&gt;
&lt;P&gt;Check out ICFP Programming Contest&amp;nbsp; 2009 this weekend, and take F#+Async+Silverlight for a spin.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9804888" width="1" height="1"&gt;</content><author><name>LukeH</name><uri>http://blogs.msdn.com/members/LukeH.aspx</uri></author><category term="icfp" scheme="http://blogs.msdn.com/lukeh/archive/tags/icfp/default.aspx" /><category term="async" scheme="http://blogs.msdn.com/lukeh/archive/tags/async/default.aspx" /><category term="fsharp" scheme="http://blogs.msdn.com/lukeh/archive/tags/fsharp/default.aspx" /><category term="silverlight" scheme="http://blogs.msdn.com/lukeh/archive/tags/silverlight/default.aspx" /></entry><entry><title>F# in Silverlight</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/lukeh/archive/2009/06/26/f-in-silverlight.aspx" /><id>http://blogs.msdn.com/lukeh/archive/2009/06/26/f-in-silverlight.aspx</id><published>2009-06-26T04:46:00Z</published><updated>2009-06-26T04:46:00Z</updated><content type="html">&lt;P&gt;Over the last couple years, there has been an explosion of interest in Silverlight.&amp;nbsp; As a .NET-based runtime, it is possible to compile Silverlight applications with any .NET language, and we’ve seen a lot of F# developers using F# in Silverlight.&amp;nbsp; However, until recently this involved building an application using the desktop version of the F# runtime, which could result in some pitfalls and mixed levels of success.&lt;/P&gt;
&lt;P&gt;With the recent F# May CTP though, we now provide a Silverlight version of the F# runtime, FSharp.Core.dll, along with the F# release.&amp;nbsp; This enables building truly first-class Silverlight components using F#.&lt;/P&gt;
&lt;P&gt;To make this easier, I’ve posted some Silverlight F# project templates and samples on Code Gallery.&amp;nbsp; &lt;/P&gt;
&lt;H2&gt;Download&lt;/H2&gt;
&lt;P&gt;&lt;A href="http://code.msdn.microsoft.com/fsharpsilverlight" mce_href="http://code.msdn.microsoft.com/fsharpsilverlight"&gt;F# Templates and Samples for Silverlight&lt;/A&gt;&lt;/P&gt;
&lt;H2&gt;Templates&lt;/H2&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/FinSilverlight_131CF/image_2.png" mce_href="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/FinSilverlight_131CF/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/lukeh/WindowsLiveWriter/FinSilverlight_131CF/image_thumb.png" width=634 height=483 mce_src="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/FinSilverlight_131CF/image_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;H2&gt;Samples&lt;/H2&gt;
&lt;H3&gt;L-Systems&lt;/H3&gt;
&lt;P&gt;Lindenmayer Systems are an interesting way of generating a variety of fractals using a simple set of rewrite rules.&amp;nbsp; Check out the fascinating book &lt;A href="http://algorithmicbotany.org/papers/abop/abop.lowquality.pdf" mce_href="http://algorithmicbotany.org/papers/abop/abop.lowquality.pdf"&gt;The Algorithmic Beauty of Plants&lt;/A&gt; for details.&amp;nbsp; The Silverlight application below uses an L-System rewriter and rendered written in F#.&lt;/P&gt;
&lt;LI&gt;&lt;B&gt;F, G, A, B&lt;/B&gt; are drawn as a move forward. &lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;+&lt;/B&gt; is a turn right. &lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;-&lt;/B&gt; is a turn right. &lt;/LI&gt;
&lt;LI&gt;&lt;B&gt;X, Y&lt;/B&gt; and anything else is skipped during rendering. &lt;EMBED height=800 type=application/x-silverlight-2 width=800 src=http://lukeh.cloudapp.net/ClientBin/LSystem.xap background="white" onerror="javascript:alert('error');" source="http://lukeh.cloudapp.net/ClientBin/LSystem.xap" mce_src="http://lukeh.cloudapp.net/ClientBin/LSystem.xap" data="data:application/x-silverlight,"&gt;&lt;/EMBED&gt; 
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/EMBED&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;open &lt;/SPAN&gt;System.Windows
&lt;SPAN style="COLOR: blue"&gt;open &lt;/SPAN&gt;System.Windows.Shapes

&lt;SPAN style="COLOR: blue"&gt;let rec internal &lt;/SPAN&gt;applyRulesInOrder rules c =
    &lt;SPAN style="COLOR: blue"&gt;match &lt;/SPAN&gt;rules &lt;SPAN style="COLOR: blue"&gt;with
    &lt;/SPAN&gt;| [] &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;string c
    | rule::rules' &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; 
        match &lt;/SPAN&gt;rule c &lt;SPAN style="COLOR: blue"&gt;with
        &lt;/SPAN&gt;| None &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;applyRulesInOrder rules' c
        | Some result &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;result

&lt;SPAN style="COLOR: blue"&gt;let internal &lt;/SPAN&gt;step rules current = 
    current 
    |&amp;gt; String.collect (applyRulesInOrder rules)

&lt;SPAN style="COLOR: blue"&gt;let internal &lt;/SPAN&gt;rotate (x,y) theta = 
    &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;x' = x * cos theta - y * sin theta
    &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;y' = x * sin theta + y * cos theta
    (x',y')

&lt;SPAN style="COLOR: blue"&gt;let rec internal &lt;/SPAN&gt;render (x,y) (dx,dy) angle points system = 
    &lt;SPAN style="COLOR: blue"&gt;match &lt;/SPAN&gt;system &lt;SPAN style="COLOR: blue"&gt;with 
    &lt;/SPAN&gt;| [] &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;(x,-y)::points
    | &lt;SPAN style="COLOR: maroon"&gt;'A'&lt;/SPAN&gt;::system' | &lt;SPAN style="COLOR: maroon"&gt;'B'&lt;/SPAN&gt;::system' | &lt;SPAN style="COLOR: maroon"&gt;'F'&lt;/SPAN&gt;::system' | &lt;SPAN style="COLOR: maroon"&gt;'G'&lt;/SPAN&gt;::system' &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;
        let &lt;/SPAN&gt;x',y' = x+dx,y+dy
        render (x',y') (dx,dy) angle ((x,-y)::points)  system'
    | &lt;SPAN style="COLOR: maroon"&gt;'+'&lt;/SPAN&gt;::system' &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;
        let &lt;/SPAN&gt;(dx',dy') = rotate (dx,dy) angle
        render (x,y) (dx',dy') angle points system'
    | &lt;SPAN style="COLOR: maroon"&gt;'-'&lt;/SPAN&gt;::system' &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;
        let &lt;/SPAN&gt;(dx',dy') = rotate (dx,dy) (-angle)
        render (x,y) (dx',dy') angle points system'
    | _::system' &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;
        &lt;/SPAN&gt;render (x,y) (dx,dy) angle points system'

&lt;SPAN style="COLOR: blue"&gt;let rec internal &lt;/SPAN&gt;applyN f n x = 
    &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;n = 0 &lt;SPAN style="COLOR: blue"&gt;then &lt;/SPAN&gt;x
    &lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;f (applyN f (n-1) x)
    
&lt;SPAN style="COLOR: blue"&gt;let internal &lt;/SPAN&gt;normalize points = 
    &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;minX = points |&amp;gt; Seq.map (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;(x,_) &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;x) |&amp;gt; Seq.min
    &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;minY = points |&amp;gt; Seq.map (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;(_,y) &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;y) |&amp;gt; Seq.min
    points |&amp;gt; List.map (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;(x,y) &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; new &lt;/SPAN&gt;Point(x-minX, y-minY))

&lt;SPAN style="COLOR: blue"&gt;type &lt;/SPAN&gt;LSystem(rulesString:string, start:string, angle:int, stepSize:int, n:int) = 
    &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;expanded,isError = 
        &lt;SPAN style="COLOR: blue"&gt;try 
            let &lt;/SPAN&gt;rules = 
                rulesString.Split([|&lt;SPAN style="COLOR: maroon"&gt;"\r"&lt;/SPAN&gt;;&lt;SPAN style="COLOR: maroon"&gt;"\n"&lt;/SPAN&gt;|], System.StringSplitOptions.RemoveEmptyEntries)
                |&amp;gt; Array.map (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;line &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;line.Split([|&lt;SPAN style="COLOR: maroon"&gt;"-&amp;gt;"&lt;/SPAN&gt;|], System.StringSplitOptions.RemoveEmptyEntries))
                |&amp;gt; Array.map (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;fromAndTo &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;(fromAndTo.[0].[0], fromAndTo.[1]))
            &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;ruleFunctions = [ &lt;SPAN style="COLOR: blue"&gt;for &lt;/SPAN&gt;(c, s) &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;rules &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; fun &lt;/SPAN&gt;x &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; if &lt;/SPAN&gt;x = c &lt;SPAN style="COLOR: blue"&gt;then &lt;/SPAN&gt;Some s &lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;None] 
            applyN (step ruleFunctions) n start, &lt;SPAN style="COLOR: blue"&gt;false
        with 
        &lt;/SPAN&gt;| e &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;""&lt;/SPAN&gt;, &lt;SPAN style="COLOR: blue"&gt;true

    member &lt;/SPAN&gt;this.Render(polyline : Polyline) = 
        &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;points = render (0.0,0.0) (float stepSize,0.0) (float angle * System.Math.PI / 180.0) [] (List.of_seq expanded)
        &lt;SPAN style="COLOR: blue"&gt;for &lt;/SPAN&gt;pt &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;normalize points &lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;polyline.Points.Add(pt)
        isError
        &lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;H3&gt;Console Control&lt;/H3&gt;
&lt;P&gt;A resuable Silverlight control providing a console emulation. The control exposes input and ouput streams akin to those on the System.Console class. Could be used to provide console input and output as part of a Silverlight application, or as a way to convert Windows Console apps to Silverlight apps.&lt;/P&gt;
&lt;P&gt;This samples hooks the Console up to a simple echo loop.&lt;/P&gt;&lt;EMBED height=300 type=application/x-silverlight-2 width=400 src=http://lukeh.cloudapp.net/ClientBin/SilverlightConsoleEcho.xap background="white" onerror="javascript:alert('error');" source="http://lukeh.cloudapp.net/ClientBin/SilverlightConsoleEcho.xap" mce_src="http://lukeh.cloudapp.net/ClientBin/SilverlightConsoleEcho.xap" data="data:application/x-silverlight,"&gt;&lt;/EMBED&gt; 
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/EMBED&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;namespace &lt;/SPAN&gt;System.Windows.Controls

&lt;SPAN style="COLOR: blue"&gt;open &lt;/SPAN&gt;System
&lt;SPAN style="COLOR: blue"&gt;open &lt;/SPAN&gt;System.IO
&lt;SPAN style="COLOR: blue"&gt;open &lt;/SPAN&gt;System.Windows
&lt;SPAN style="COLOR: blue"&gt;open &lt;/SPAN&gt;System.Windows.Controls
&lt;SPAN style="COLOR: blue"&gt;open &lt;/SPAN&gt;System.Windows.Input
&lt;SPAN style="COLOR: blue"&gt;open &lt;/SPAN&gt;SilverlightContrib.Utilities.ClipboardHelper
&lt;SPAN style="COLOR: blue"&gt;open &lt;/SPAN&gt;System.Text

&lt;SPAN style="COLOR: green"&gt;// A shared base implementation of Stream for 
// use by the console input and output streams
&lt;/SPAN&gt;[&amp;lt;AbstractClass&amp;gt;]
&lt;SPAN style="COLOR: blue"&gt;type private &lt;/SPAN&gt;ConsoleStream(isRead) = 
    &lt;SPAN style="COLOR: blue"&gt;inherit &lt;/SPAN&gt;Stream() 
    &lt;SPAN style="COLOR: blue"&gt;override &lt;/SPAN&gt;this.CanRead = isRead
    &lt;SPAN style="COLOR: blue"&gt;override &lt;/SPAN&gt;this.CanWrite = not isRead
    &lt;SPAN style="COLOR: blue"&gt;override &lt;/SPAN&gt;this.CanSeek = &lt;SPAN style="COLOR: blue"&gt;false
    override &lt;/SPAN&gt;this.Position 
        &lt;SPAN style="COLOR: blue"&gt;with &lt;/SPAN&gt;get() = raise (&lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;NotSupportedException(&lt;SPAN style="COLOR: maroon"&gt;"Console stream does not have a position"&lt;/SPAN&gt;))
        &lt;SPAN style="COLOR: blue"&gt;and  &lt;/SPAN&gt;set(v) = raise (&lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;NotSupportedException(&lt;SPAN style="COLOR: maroon"&gt;"Console stream does not have a position"&lt;/SPAN&gt;))
    &lt;SPAN style="COLOR: blue"&gt;override &lt;/SPAN&gt;this.Length = raise (&lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;NotSupportedException(&lt;SPAN style="COLOR: maroon"&gt;"Console stream does not have a length"&lt;/SPAN&gt;))
    &lt;SPAN style="COLOR: blue"&gt;override &lt;/SPAN&gt;this.Flush() = ()
    &lt;SPAN style="COLOR: blue"&gt;override &lt;/SPAN&gt;this.Seek(offset, origin) = raise (&lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;NotSupportedException(&lt;SPAN style="COLOR: maroon"&gt;"Console stream cannot seek"&lt;/SPAN&gt;)) 
    &lt;SPAN style="COLOR: blue"&gt;override &lt;/SPAN&gt;this.SetLength(v) = raise (&lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;NotSupportedException(&lt;SPAN style="COLOR: maroon"&gt;"Console stream does not have a length"&lt;/SPAN&gt;)) 

&lt;SPAN style="COLOR: green"&gt;/// A control representing a Console window
/// Provides an InputStream and OutputStream
/// for reading an writing character input.
/// Also supports copy/paste on some browsers
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;type &lt;/SPAN&gt;SilverlightConsole() &lt;SPAN style="COLOR: blue"&gt;as &lt;/SPAN&gt;self = 
    &lt;SPAN style="COLOR: blue"&gt;inherit &lt;/SPAN&gt;TextBox()
    
    &lt;SPAN style="COLOR: green"&gt;// The queue of user input which has been collected by the 
    // console, but not yet read from the input stream
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;readQueue = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;System.Collections.Generic.Queue&amp;lt;int&amp;gt;()
    
    &lt;SPAN style="COLOR: green"&gt;// A stream that reads characters from user input
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;inputStream = 
        { &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;ConsoleStream(&lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;) &lt;SPAN style="COLOR: blue"&gt;with
            override &lt;/SPAN&gt;this.Write(buffer,offset,count) = 
                raise (&lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;NotSupportedException(&lt;SPAN style="COLOR: maroon"&gt;"Cannot write from Console input stream"&lt;/SPAN&gt;)) 
            &lt;SPAN style="COLOR: blue"&gt;override &lt;/SPAN&gt;this.Read(buffer,offset,count) = 
                &lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;System.Diagnostics.Debug.WriteLine(&lt;SPAN style="COLOR: maroon"&gt;"Starting to read {0} bytes"&lt;/SPAN&gt;, count)
                &lt;SPAN style="COLOR: blue"&gt;let rec &lt;/SPAN&gt;waitForAtLeastOneByte() = 
                    &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;shouldSleep = ref &lt;SPAN style="COLOR: blue"&gt;true
                    let &lt;/SPAN&gt;ret = ref [||]
                    lock readQueue  (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;() &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;
                        &lt;/SPAN&gt;shouldSleep := readQueue.Count &amp;lt; 1
                        &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;not !shouldSleep &lt;SPAN style="COLOR: blue"&gt;then 
                            let &lt;/SPAN&gt;lengthToRead = min readQueue.Count count
                            ret := Array.init lengthToRead (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;i &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;byte (readQueue.Dequeue())))
                    &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;!shouldSleep
                    &lt;SPAN style="COLOR: blue"&gt;then &lt;/SPAN&gt;System.Threading.Thread.Sleep(100); waitForAtLeastOneByte()
                    &lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;!ret
                &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;bytes = waitForAtLeastOneByte()
                System.Array.Copy(bytes, 0, buffer, offset, bytes.Length)
                &lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;System.Diagnostics.Debug.WriteLine(&lt;SPAN style="COLOR: maroon"&gt;"Finished reading {0} bytes"&lt;/SPAN&gt;, bytes.Length)
                bytes.Length
        }
    
    &lt;SPAN style="COLOR: green"&gt;// A stream that sends character output onto the console screen
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;outputStream = 
        { &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;ConsoleStream(&lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;) &lt;SPAN style="COLOR: blue"&gt;with
            override &lt;/SPAN&gt;this.Read(buffer,offset,count) = 
                raise (&lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;NotSupportedException(&lt;SPAN style="COLOR: maroon"&gt;"Cannot read from Console output stream"&lt;/SPAN&gt;)) 
            &lt;SPAN style="COLOR: blue"&gt;override &lt;/SPAN&gt;this.Write(buffer,offset,count) = 
                &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;isDelete = offset &amp;lt; 0
                &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;newText = 
                    &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;isDelete 
                    &lt;SPAN style="COLOR: blue"&gt;then &lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;""
                    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;UnicodeEncoding.UTF8.GetString(buffer, offset, count)
                &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;_ = self.Dispatcher.BeginInvoke(&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;() &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;
                    if &lt;/SPAN&gt;isDelete &lt;SPAN style="COLOR: blue"&gt;then 
                        if &lt;/SPAN&gt;self.Text.Length &amp;gt;= count &lt;SPAN style="COLOR: blue"&gt;then 
                            &lt;/SPAN&gt;self.Text &amp;lt;- self.Text.Substring(0, self.Text.Length - count)
                    &lt;SPAN style="COLOR: blue"&gt;else
                        do &lt;/SPAN&gt;self.Text &amp;lt;- self.Text + newText
                    &lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;self.SelectionStart &amp;lt;- self.Text.Length
                    &lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;self.SelectionLength &amp;lt;- 0)
                ()
        }
   
    &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;shiftNumbers = [|&lt;SPAN style="COLOR: maroon"&gt;')'&lt;/SPAN&gt;;&lt;SPAN style="COLOR: maroon"&gt;'!'&lt;/SPAN&gt;;&lt;SPAN style="COLOR: maroon"&gt;'@'&lt;/SPAN&gt;;&lt;SPAN style="COLOR: maroon"&gt;'#'&lt;/SPAN&gt;;&lt;SPAN style="COLOR: maroon"&gt;'$'&lt;/SPAN&gt;;&lt;SPAN style="COLOR: maroon"&gt;'%'&lt;/SPAN&gt;;&lt;SPAN style="COLOR: maroon"&gt;'^'&lt;/SPAN&gt;;&lt;SPAN style="COLOR: maroon"&gt;'&amp;amp;'&lt;/SPAN&gt;;&lt;SPAN style="COLOR: maroon"&gt;'*'&lt;/SPAN&gt;;&lt;SPAN style="COLOR: maroon"&gt;'('&lt;/SPAN&gt;|]
    &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;currentInputLine = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;System.Collections.Generic.List&amp;lt;int&amp;gt;()
    
    &lt;SPAN style="COLOR: green"&gt;// Handles key down events
    // Processes the pressed key and turns it into console input
    // Also echos the pressed key to the console 
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;keyDownHandler(keyArgs : KeyEventArgs) = 
        &lt;SPAN style="COLOR: blue"&gt;try
            do &lt;/SPAN&gt;keyArgs.Handled &amp;lt;- &lt;SPAN style="COLOR: blue"&gt;true
            let &lt;/SPAN&gt;shiftDown = Keyboard.Modifiers &amp;amp;&amp;amp;&amp;amp; ModifierKeys.Shift &amp;lt;&amp;gt; (enum 0)
            &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;ctrlDown = Keyboard.Modifiers &amp;amp;&amp;amp;&amp;amp; ModifierKeys.Control &amp;lt;&amp;gt; (enum 0)
            &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;p = keyArgs.PlatformKeyCode
            &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;ctrlDown || keyArgs.Key = Key.Ctrl &lt;SPAN style="COLOR: blue"&gt;then
                if &lt;/SPAN&gt;keyArgs.Key = Key.V &lt;SPAN style="COLOR: blue"&gt;then
                    &lt;/SPAN&gt;lock currentInputLine (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;() &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;
                        let &lt;/SPAN&gt;clipboard = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;ClipboardHelper()
                        &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;fromClipboard = clipboard.GetData()
                        &lt;SPAN style="COLOR: blue"&gt;for &lt;/SPAN&gt;c &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;fromClipboard &lt;SPAN style="COLOR: blue"&gt;do
                            do &lt;/SPAN&gt;currentInputLine.Add(int c)
                            outputStream.WriteByte(byte c)
                            &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;c = &lt;SPAN style="COLOR: maroon"&gt;'\n' &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;then
                                for &lt;/SPAN&gt;i &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;currentInputLine &lt;SPAN style="COLOR: blue"&gt;do 
                                    do &lt;/SPAN&gt;System.Diagnostics.Debug.WriteLine(&lt;SPAN style="COLOR: maroon"&gt;"Enqueued {0}"&lt;/SPAN&gt;, char i)
                                    &lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;readQueue.Enqueue(i)
                                &lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;currentInputLine.Clear()
                    )
                &lt;SPAN style="COLOR: blue"&gt;elif &lt;/SPAN&gt;keyArgs.Key = Key.C &lt;SPAN style="COLOR: blue"&gt;then
                    let &lt;/SPAN&gt;text = self.SelectedText
                    &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;clipboard = &lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;ClipboardHelper()
                    clipboard.SetData(text)
            &lt;SPAN style="COLOR: blue"&gt;else
                &lt;/SPAN&gt;System.Diagnostics.Debug.WriteLine(&lt;SPAN style="COLOR: maroon"&gt;"Got key {0} {1} {2}"&lt;/SPAN&gt;, p, char p, keyArgs.Key)
                &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;ascii = 
                    &lt;SPAN style="COLOR: blue"&gt;match &lt;/SPAN&gt;p &lt;SPAN style="COLOR: blue"&gt;with
                    &lt;/SPAN&gt;| n &lt;SPAN style="COLOR: blue"&gt;when &lt;/SPAN&gt;n &amp;gt;= 65 &amp;amp;&amp;amp; n &amp;lt;= 90 &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; if &lt;/SPAN&gt;shiftDown &lt;SPAN style="COLOR: blue"&gt;then &lt;/SPAN&gt;p &lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;p+32
                    | n &lt;SPAN style="COLOR: blue"&gt;when &lt;/SPAN&gt;n &amp;gt;= 48 &amp;amp;&amp;amp; n &amp;lt;= 57 &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; if &lt;/SPAN&gt;shiftDown &lt;SPAN style="COLOR: blue"&gt;then &lt;/SPAN&gt;int shiftNumbers.[p-48] &lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;p
                    | 8 &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;8 &lt;SPAN style="COLOR: green"&gt;// backspace
                    &lt;/SPAN&gt;| 13 &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;'\n'
                    &lt;/SPAN&gt;| 32 &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;' '
                    &lt;/SPAN&gt;| 186 &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; if &lt;/SPAN&gt;shiftDown &lt;SPAN style="COLOR: blue"&gt;then &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;':' &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;';'
                    &lt;/SPAN&gt;| 187 &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; if &lt;/SPAN&gt;shiftDown &lt;SPAN style="COLOR: blue"&gt;then &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;'+' &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;'='
                    &lt;/SPAN&gt;| 188 &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; if &lt;/SPAN&gt;shiftDown &lt;SPAN style="COLOR: blue"&gt;then &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;'&amp;lt;' &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;','
                    &lt;/SPAN&gt;| 189 &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; if &lt;/SPAN&gt;shiftDown &lt;SPAN style="COLOR: blue"&gt;then &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;'_' &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;'-'
                    &lt;/SPAN&gt;| 190 &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; if &lt;/SPAN&gt;shiftDown &lt;SPAN style="COLOR: blue"&gt;then &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;'&amp;gt;' &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;'.'
                    &lt;/SPAN&gt;| 191 &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; if &lt;/SPAN&gt;shiftDown &lt;SPAN style="COLOR: blue"&gt;then &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;'?' &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;'/'
                    &lt;/SPAN&gt;| 192 &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; if &lt;/SPAN&gt;shiftDown &lt;SPAN style="COLOR: blue"&gt;then &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;'~' &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;'`'
                    &lt;/SPAN&gt;| 219 &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; if &lt;/SPAN&gt;shiftDown &lt;SPAN style="COLOR: blue"&gt;then &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;'{' &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;'['
                    &lt;/SPAN&gt;| 220 &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; if &lt;/SPAN&gt;shiftDown &lt;SPAN style="COLOR: blue"&gt;then &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;'|' &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;'\\'
                    &lt;/SPAN&gt;| 221 &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; if &lt;/SPAN&gt;shiftDown &lt;SPAN style="COLOR: blue"&gt;then &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;'}' &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;']'
                    &lt;/SPAN&gt;| 222 &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; if &lt;/SPAN&gt;shiftDown &lt;SPAN style="COLOR: blue"&gt;then &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;'\"' &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;else &lt;/SPAN&gt;int &lt;SPAN style="COLOR: maroon"&gt;'\''
                    &lt;/SPAN&gt;| _ &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;-1
                &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;ascii = 8 &lt;SPAN style="COLOR: blue"&gt;then
                    &lt;/SPAN&gt;lock currentInputLine (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;() &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;
                        if &lt;/SPAN&gt;currentInputLine.Count &amp;gt; 0 &lt;SPAN style="COLOR: blue"&gt;then &lt;/SPAN&gt;currentInputLine.RemoveAt(currentInputLine.Count - 1)
                        outputStream.Write([||], -1, 1)
                    )
                &lt;SPAN style="COLOR: blue"&gt;elif &lt;/SPAN&gt;ascii &amp;gt; 0 &lt;SPAN style="COLOR: blue"&gt;then
                    &lt;/SPAN&gt;lock currentInputLine (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;() &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;
                        do &lt;/SPAN&gt;currentInputLine.Add(ascii)
                        outputStream.WriteByte(byte ascii)
                    )
                &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;ascii = int &lt;SPAN style="COLOR: maroon"&gt;'\n' &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;then 
                    &lt;/SPAN&gt;lock currentInputLine (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;() &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;
                        for &lt;/SPAN&gt;i &lt;SPAN style="COLOR: blue"&gt;in &lt;/SPAN&gt;currentInputLine &lt;SPAN style="COLOR: blue"&gt;do 
                            do &lt;/SPAN&gt;System.Diagnostics.Debug.WriteLine(&lt;SPAN style="COLOR: maroon"&gt;"Enqueued {0}"&lt;/SPAN&gt;, char i)
                            &lt;SPAN style="COLOR: blue"&gt;if &lt;/SPAN&gt;i = 10 &lt;SPAN style="COLOR: blue"&gt;then
                                do &lt;/SPAN&gt;readQueue.Enqueue(13)
                            &lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;readQueue.Enqueue(i)
                        &lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;currentInputLine.Clear())
                &lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;self.SelectionStart &amp;lt;- self.Text.Length
                &lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;self.SelectionLength &amp;lt;- 0
        &lt;SPAN style="COLOR: blue"&gt;with 
        &lt;/SPAN&gt;| e &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;System.Diagnostics.Debug.WriteLine(e)
    
    &lt;SPAN style="COLOR: green"&gt;// Lazily initialized StreamReader/StreamWriter
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;outReader = &lt;SPAN style="COLOR: blue"&gt;lazy &lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;System.IO.StreamWriter(outputStream, Encoding.UTF8, 256, AutoFlush=&lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;))
    &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;inReader = &lt;SPAN style="COLOR: blue"&gt;lazy &lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;new &lt;/SPAN&gt;System.IO.StreamReader(inputStream, Encoding.UTF8, &lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;, 256))

    &lt;SPAN style="COLOR: green"&gt;// Manually handle the Return key so we can accept newlines
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;self.AcceptsReturn &amp;lt;- &lt;SPAN style="COLOR: blue"&gt;true
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// Make sure a vertical scrollbar appears when needed
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;self.VerticalScrollBarVisibility &amp;lt;- ScrollBarVisibility.Auto
    &lt;SPAN style="COLOR: green"&gt;// Make the control read-only so that users cannot move the cusor or change the contents
    // Unfortunatley, this also greys it out - ideally we could seperate theese two.
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;self.IsReadOnly &amp;lt;- &lt;SPAN style="COLOR: blue"&gt;true
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: green"&gt;// Hookup the keyDownHandler
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;self.KeyDown.Add(keyDownHandler)
    
    &lt;SPAN style="COLOR: green"&gt;/// The raw input stream for the Console
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;member &lt;/SPAN&gt;this.InputStream = inputStream :&amp;gt; Stream
    &lt;SPAN style="COLOR: green"&gt;/// The raw ouput stream for the Console
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;member &lt;/SPAN&gt;this.OutputStream = outputStream :&amp;gt; Stream
    
    &lt;SPAN style="COLOR: green"&gt;/// A StreamWriter for writing to the Console
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;member &lt;/SPAN&gt;this.Out = outReader.Value
    &lt;SPAN style="COLOR: green"&gt;/// A StreamReader for reading from the Console
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;member &lt;/SPAN&gt;this.In = inReader.Value&lt;/PRE&gt;
&lt;H2&gt;Summary&lt;/H2&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;Try out F# with Silverlight using the F# May CTP and the F# for Silverlight templates.&lt;/P&gt;&lt;/LI&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9804771" width="1" height="1"&gt;</content><author><name>LukeH</name><uri>http://blogs.msdn.com/members/LukeH.aspx</uri></author><category term="fsharp" scheme="http://blogs.msdn.com/lukeh/archive/tags/fsharp/default.aspx" /><category term="silverlight" scheme="http://blogs.msdn.com/lukeh/archive/tags/silverlight/default.aspx" /></entry><entry><title>F# on Windows Azure</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/lukeh/archive/2008/10/28/f-on-windows-azure.aspx" /><id>http://blogs.msdn.com/lukeh/archive/2008/10/28/f-on-windows-azure.aspx</id><published>2008-10-28T20:40:07Z</published><updated>2008-10-28T20:40:07Z</updated><content type="html">&lt;p&gt;&lt;a href="http://www.microsoft.com/azure/default.mspx"&gt;Windows Azure&lt;/a&gt; was announced yesterday, and along with it, the first CTP of the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=BB893FB0-AD04-4FE8-BB04-0C5E4278D3E9&amp;amp;displaylang=en"&gt;SDK&lt;/a&gt; and &lt;a href="http://go.microsoft.com/fwlink/?LinkId=128752"&gt;Visual Studio tools&lt;/a&gt;.&amp;#160; If you haven’t yet tried it, go &lt;a href="http://www.microsoft.com/azure/register.mspx"&gt;take a look&lt;/a&gt;.&amp;#160; On top of serving as a hosting service for web applications, Azure also provides a really simple way to do distributed compute and storage in the cloud.&lt;/p&gt;  &lt;p&gt;Azure supports running .NET applications, which means you can build Azure worker roles using F#! The tools released with Azure don’t have F# support out of the box though, so I’ve posted a few simple templates and samples up on Code Gallery.&lt;/p&gt;  &lt;h2&gt;Download&lt;/h2&gt;  &lt;p&gt;&lt;a href="http://code.msdn.microsoft.com/fsharpazure/"&gt;F# Templates and Samples for Windows Azure&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;Templates&lt;/h2&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/FonWindowsAzure_801/image_2.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="390" alt="image" src="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/FonWindowsAzure_801/image_thumb.png" width="634" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h2&gt;Cloud WebCrawl Sample&lt;/h2&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;#light
namespace &lt;/span&gt;SearchEngine_WorkerRole

&lt;span style="color: blue"&gt;open &lt;/span&gt;System
&lt;span style="color: blue"&gt;open &lt;/span&gt;System.Threading
&lt;span style="color: blue"&gt;open &lt;/span&gt;Microsoft.ServiceHosting.ServiceRuntime
&lt;span style="color: blue"&gt;open &lt;/span&gt;System.Net
&lt;span style="color: blue"&gt;open &lt;/span&gt;System.IO
&lt;span style="color: blue"&gt;open &lt;/span&gt;System.Text.RegularExpressions
&lt;span style="color: blue"&gt;open &lt;/span&gt;Microsoft.Samples.ServiceHosting.StorageClient;
&lt;span style="color: blue"&gt;open &lt;/span&gt;System.Web
&lt;span style="color: blue"&gt;open &lt;/span&gt;System.Runtime.Serialization.Formatters.Binary

&lt;span style="color: blue"&gt;type &lt;/span&gt;WorkerRole() =
    &lt;span style="color: blue"&gt;inherit &lt;/span&gt;RoleEntryPoint()

    &lt;span style="color: green"&gt;// The page to start crawling from
    &lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;startpage = &lt;span style="color: maroon"&gt;@&amp;quot;http://blogs.msdn.com/lukeh&amp;quot;
    &lt;/span&gt;&lt;span style="color: green"&gt;// The filter to apply to links while crawling
    &lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;pageFilter = &lt;span style="color: blue"&gt;fun &lt;/span&gt;(url:string) &lt;span style="color: blue"&gt;-&amp;gt; &lt;/span&gt;url.StartsWith(&lt;span style="color: maroon"&gt;&amp;quot;http://blogs.msdn.com/&amp;quot;&lt;/span&gt;)

    &lt;span style="color: green"&gt;/// Get the contents of a given url
    &lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;http(url: string) = 
        &lt;span style="color: blue"&gt;let &lt;/span&gt;req    = WebRequest.Create(url) 
        &lt;span style="color: blue"&gt;use &lt;/span&gt;resp   = req.GetResponse()
        &lt;span style="color: blue"&gt;use &lt;/span&gt;stream = resp.GetResponseStream() 
        &lt;span style="color: blue"&gt;use &lt;/span&gt;reader = &lt;span style="color: blue"&gt;new &lt;/span&gt;StreamReader(stream) 
        &lt;span style="color: blue"&gt;let &lt;/span&gt;html   = reader.ReadToEnd()
        html

    &lt;span style="color: green"&gt;/// Get the links from a page of HTML
    &lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;linkPat = &lt;span style="color: maroon"&gt;&amp;quot;href=\s*\&amp;quot;[^\&amp;quot;h]*(http://[^&amp;amp;\&amp;quot;]*)\&amp;quot;&amp;quot;
    &lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;getLinks text =  [ &lt;span style="color: blue"&gt;for &lt;/span&gt;m &lt;span style="color: blue"&gt;in &lt;/span&gt;Regex.Matches(text,linkPat)  &lt;span style="color: blue"&gt;-&amp;gt; &lt;/span&gt;m.Groups.Item(1).Value ]
    
    &lt;span style="color: green"&gt;/// Handle the message msg using the given queue and blob container
    &lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;HandleMessage (msg : Message) (queue : MessageQueue, container: BlobContainer) =
        &lt;span style="color: green"&gt;// There was a new item, get the contents
        &lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;url = msg.ContentAsString();
        &lt;span style="color: blue"&gt;let &lt;/span&gt;urlBlobName = HttpUtility.UrlEncode(url)
        &lt;span style="color: green"&gt;// Don't get the page if we've already seen it
        &lt;/span&gt;&lt;span style="color: blue"&gt;if &lt;/span&gt;not(container.DoesBlobExist(urlBlobName)) 
        &lt;span style="color: blue"&gt;then
            do &lt;/span&gt;RoleManager.WriteToLog(&lt;span style="color: maroon"&gt;&amp;quot;Information&amp;quot;&lt;/span&gt;, String.Format(&lt;span style="color: maroon"&gt;&amp;quot;Handling new url: '{0}'&amp;quot;&lt;/span&gt;, url));
            &lt;span style="color: blue"&gt;try
                &lt;/span&gt;&lt;span style="color: green"&gt;// Get the contents of the page
                &lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;content = http url
                &lt;span style="color: green"&gt;// Store the page into the blob store
                &lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;props = &lt;span style="color: blue"&gt;new &lt;/span&gt;BlobProperties(urlBlobName)
                &lt;span style="color: blue"&gt;let &lt;/span&gt;_ = container.CreateBlob(props, &lt;span style="color: blue"&gt;new &lt;/span&gt;BlobContents(System.Text.UTF8Encoding.Default.GetBytes(content)), &lt;span style="color: blue"&gt;true&lt;/span&gt;);
                
                &lt;span style="color: green"&gt;// Get the links from the page
                &lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;links = getLinks content
                
                &lt;span style="color: green"&gt;// Filter down the links and then create a new work item for each
                &lt;/span&gt;links
                |&amp;gt; Seq.filter pageFilter
                |&amp;gt; Seq.distinct
                |&amp;gt; Seq.filter (&lt;span style="color: blue"&gt;fun &lt;/span&gt;link &lt;span style="color: blue"&gt;-&amp;gt; &lt;/span&gt;not(container.DoesBlobExist(HttpUtility.UrlEncode(link))))
                |&amp;gt; Seq.iter (&lt;span style="color: blue"&gt;fun &lt;/span&gt;link &lt;span style="color: blue"&gt;-&amp;gt; &lt;/span&gt;queue.PutMessage(&lt;span style="color: blue"&gt;new &lt;/span&gt;Message(link)) |&amp;gt; ignore)
                queue.DeleteMessage(msg) |&amp;gt; ignore
            &lt;span style="color: blue"&gt;with
            &lt;/span&gt;| _ &lt;span style="color: blue"&gt;-&amp;gt;&lt;/span&gt;()
    
    &lt;span style="color: green"&gt;/// Main loop of worker process
    &lt;/span&gt;&lt;span style="color: blue"&gt;let rec &lt;/span&gt;Loop (queue : MessageQueue, container: BlobContainer) = 
        &lt;span style="color: green"&gt;// Get the next page to crawl from the queue
        &lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;msg = queue.GetMessage(240);
        &lt;span style="color: blue"&gt;if &lt;/span&gt;msg = &lt;span style="color: blue"&gt;null
        then &lt;/span&gt;Thread.Sleep(1000)
        &lt;span style="color: blue"&gt;else &lt;/span&gt;HandleMessage msg (queue, container)
        Loop(queue,container)
    
    &lt;span style="color: blue"&gt;override &lt;/span&gt;wp.Start() =
        &lt;span style="color: green"&gt;// Initialize the Blob storage
        &lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;blobStorage = BlobStorage.Create(StorageAccountInfo.GetDefaultBlobStorageAccountFromConfiguration());
        &lt;span style="color: blue"&gt;let &lt;/span&gt;container = blobStorage.GetBlobContainer(&lt;span style="color: maroon"&gt;&amp;quot;searchengine&amp;quot;&lt;/span&gt;);
        &lt;span style="color: blue"&gt;let &lt;/span&gt;a = container.CreateContainer(&lt;span style="color: blue"&gt;null&lt;/span&gt;, ContainerAccessControl.Public);

        &lt;span style="color: green"&gt;// Initialize the Queue storage
        &lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;queueStorage = QueueStorage.Create(StorageAccountInfo.GetDefaultQueueStorageAccountFromConfiguration());
        &lt;span style="color: blue"&gt;let &lt;/span&gt;queue = queueStorage.GetQueue(&lt;span style="color: maroon"&gt;&amp;quot;searchworker&amp;quot;&lt;/span&gt;);
        &lt;span style="color: blue"&gt;let &lt;/span&gt;b = queue.CreateQueue()
        
        &lt;span style="color: green"&gt;// Put an initial message in the queue, using the start page
        &lt;/span&gt;&lt;span style="color: blue"&gt;let &lt;/span&gt;c = queue.PutMessage(&lt;span style="color: blue"&gt;new &lt;/span&gt;Message(startpage));
        
        &lt;span style="color: green"&gt;// Begin the main loop, processing messages in the queue
        &lt;/span&gt;Loop(queue, container)
        
    &lt;span style="color: blue"&gt;override &lt;/span&gt;wp.GetHealthStatus() = RoleStatus.Healthy&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;Worker Roles&lt;/h5&gt;

&lt;p&gt;The code above defines the implementation of a Worker Role – a process which runs in the background, waiting for work to do, and then processing these work requests.&amp;#160; The worker role is set to run 4 instance simultaneously, which means that there will be 4 instances of this worker processing work items as they come in.&amp;#160; This gives an implicit parallelism – in fact, the initial release of Azure will run one process per core, so you really are getting effective parallelism this way.&amp;#160; Notice also that this requires that the worker processes are inherently stateless.&amp;#160; Both aspects make typical functional design approaches that are common in F# natural for developing these worker roles.&lt;/p&gt;

&lt;h5&gt;Queues and Blobs&lt;/h5&gt;

&lt;p&gt;This sample uses two of the three data formats supported by Windows Azure.&amp;#160; The queue storage holds the work items. The blob storage holds the pages visited during the web crawl.&amp;#160; When an instance of the worker role Starts, it connects to the blob store and the queue store, then puts an initial work item in the queue and goes into a loop processing work items out of the queue.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;
Ideas for any other interesting F# applications on Windows Azure?&amp;#160; Download the &lt;a href="http://code.msdn.microsoft.com/fsharpazure"&gt;templates and samples&lt;/a&gt;.&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9020608" width="1" height="1"&gt;</content><author><name>LukeH</name><uri>http://blogs.msdn.com/members/LukeH.aspx</uri></author></entry><entry><title>Standard Deviation and Event-based Programming</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/lukeh/archive/2008/10/10/standard-deviation-and-event-based-programming.aspx" /><id>http://blogs.msdn.com/lukeh/archive/2008/10/10/standard-deviation-and-event-based-programming.aspx</id><published>2008-10-10T21:47:00Z</published><updated>2008-10-10T21:47:00Z</updated><content type="html">&lt;P&gt;A couple weeks ago, I had the opportunity to do a really fun presentation on F# at the &lt;A href="http://dotnet.meetup.com/120/calendar/8580054/?a=cr1p_grp" mce_href="http://dotnet.meetup.com/120/calendar/8580054/?a=cr1p_grp"&gt;.NET Meetup&lt;/A&gt; in New York.&amp;nbsp; At the end, I got a great question, which I talked about a little at the presentation, but thought I’d talk about further in a blog post.&lt;/P&gt;
&lt;P&gt;The following isn’t exactly how the conversation went - but roughly captures what we talked about, and covers a lot of fun F# topics.&amp;nbsp; There’s some allusions here to ideas from statistics, time-series analysis, &lt;A href="http://en.wikipedia.org/wiki/Complex_event_processing" mce_href="http://en.wikipedia.org/wiki/Complex_event_processing"&gt;CEP&lt;/A&gt; and &lt;A href="http://en.wikipedia.org/wiki/Functional_reactive_programming" mce_href="http://en.wikipedia.org/wiki/Functional_reactive_programming"&gt;FRP&lt;/A&gt;.&lt;/P&gt;
&lt;H3&gt;“How would you compute standard deviation over a stream of data in F#?”&lt;/H3&gt;
&lt;P&gt;&lt;A href="http://en.wikipedia.org/wiki/Standard_deviation" mce_href="http://en.wikipedia.org/wiki/Standard_deviation"&gt;Standard deviation&lt;/A&gt; is a pretty straightforward computation with F#.&amp;nbsp; There’s a few ways to write it, but with “average” and “average_by” built-in, they provide a particularly simple option. &lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: green"&gt;/// Square a number
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;sqr x = x * x

&lt;SPAN style="COLOR: green"&gt;/// Compute the standard deviation of a list of numbers
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;stddev nums = 
    &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;mean = nums |&amp;gt; List.average
    &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;variance = nums |&amp;gt; List.average_by (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;x &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;sqr(x - mean))
    sqrt(variance)&lt;/PRE&gt;
&lt;H3&gt;“Okay – but what if I want the inputs to be long, potentially infinite sources of data?”&lt;/H3&gt;
&lt;P&gt;The previous function worked over lists.&amp;nbsp; We can change it to work over sequences (IEnumerables) instead.&amp;nbsp; Pleasantly, it’s basically the same code.&amp;nbsp; But the result of working over sequences is that this function will work with any sort of data.&amp;nbsp; It could be a sequence of numbers that result from a LINQ to SQL query, it could be a sequence of numbers read lazily from a very long file, etc.&amp;nbsp; &lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: green"&gt;/// Compute the standard deviation of a sequence of numbers
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;stddevSeq numSeq = 
    &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;mean = numSeq |&amp;gt; Seq.average
    &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;variance = numSeq |&amp;gt; Seq.average_by (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;x &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;sqr(x - mean))
    sqrt(variance)&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;H3&gt;“That’s computing what I want, but can I get all the partial results as my stream of data is processed? ”&lt;/H3&gt;
&lt;P&gt;This makes things more interesting.&amp;nbsp; Instead of just computing the standard deviation, we really want to do an “online” calculation, where we compute enough information so that as each new datapoint comes in, we can easily produce the new standard deviation.&amp;nbsp; This is a different algorithmic approach to the same mathematical formula.&amp;nbsp; Luckily, wikipedia has what we need- an &lt;A href="http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance" mce_href="http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance"&gt;on-line algorithm for standard deviation&lt;/A&gt; from Knuth.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: green"&gt;/// Compute the running mean and standard deviation
/// over a sequence of numbers
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;meanAndStdDev nums = 
    &lt;SPAN style="COLOR: green"&gt;// A function which updates the on-line computation of 
    // n, mean and M2 given a new datapoint x
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;newValues (n, mean, M2) x = 
        &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;n' = n+1.
        &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;delta = x - mean
        &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;mean' = mean + delta/n'
        &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;M2' = M2 + delta*(x - mean')
        (n', mean', M2')
    &lt;SPAN style="COLOR: green"&gt;// The initial vaues of n, mean and M2
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;startValues = (0., 0., 0.)
    &lt;SPAN style="COLOR: green"&gt;// The resulting event stream is a scan over the input events 
    &lt;/SPAN&gt;nums 
    |&amp;gt; Seq.scan newValues startValues
    |&amp;gt; Seq.map (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;(n, mean, M2) &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;(mean, sqrt(M2/(n))))&lt;/PRE&gt;
&lt;P&gt;This time the code has a few interesting features:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;A local function “newValues” updates n, mean and M2 based on old values and a new datapoint x.&amp;nbsp; Notice that (a) this is strikingly similar to the pseudo-code in the &lt;A href="http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance" mce_href="http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance"&gt;wikipedia&lt;/A&gt; article but (b) this is a functional implementation, so instead of changing the values, we just compute new ones.&lt;/LI&gt;
&lt;LI&gt;The function “Seq.scan” takes care of the heavy lifting.&amp;nbsp; This function, and the related “fold” and “reduce” can be used to capture many common design patterns seen in “&lt;A 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;”.&amp;nbsp; Scan walks across an input collection applying a function to it’s current accumulator argument, and returning a collection of the results that it builds up as it goes.&amp;nbsp; If you’ve haven’t written code using these before, they can feel uncomfortable at first, but after you’ve used each of these once or twice, you’ll notice them as common patterns that you are currently encoding as for loops, if statements and local state in your programs.&amp;nbsp; “scan” and it’s related functions give us the ability to name that design pattern and then re-use it – resulting in more declarative code.&lt;/LI&gt;&lt;/OL&gt;
&lt;H3&gt;“Perfect!&amp;nbsp; But my actual stream of data (stock ticker prices) is long running, and will provide new data points periodically over minutes, days and weeks.”&lt;/H3&gt;
&lt;P&gt;Another fun twist on the problem!&amp;nbsp; Sequences (IEnumerables) have the property that the producer of the data offers up a way to ask for more, and the consumer is in charge of pulling it out.&amp;nbsp; While it’s doing so, it’s busy the whole time, so if the producer&amp;nbsp; doesn’t have the data yet, it will have to block waiting for it to be available.&amp;nbsp; This is not what you want in the long running case, where instead we want to think about the data stream as a sequence of &lt;STRONG&gt;events&lt;/STRONG&gt;.&amp;nbsp; With events, the consumer offers up a way to deal with new data whenever it’s available, and the producer is in charge of pushing the new data points out.&amp;nbsp; For the same reasons that there is so much interest in smart phones with push email, we should all want our long-running data streams to be event based instead of sequence based.&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;boundedMouseMax = 
    form.MouseMove 
    |&amp;gt; Event.filter (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;mea &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;mea.X &amp;gt; 10 &amp;amp;&amp;amp; mea.Y &amp;gt; 10 &amp;amp;&amp;amp; mea.X &amp;lt; 90 &amp;amp;&amp;amp; mea.Y &amp;lt; 90)
    |&amp;gt; Event.map (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;mea &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;max mea.X mea.Y)&lt;/PRE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;boundedMouseMax |&amp;gt; Event.listen (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;maxCoord &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;printfn &lt;SPAN style="COLOR: maroon"&gt;"max is: %A" &lt;/SPAN&gt;maxCoord)&lt;/PRE&gt;
&lt;P&gt;Events in F# are just standard .NET events.&amp;nbsp; But F# allows you to program with these events in a “first-class” way, meaning you can pass them around as data, and there are functions in the “Event” module for taking events and generating new events from them.&amp;nbsp; For instance, we could take a mouse move event and call “Event.filter” to filter out any time it is outside a bounding box, then “Event.map” to pick the larger of the X or Y coordinate of the mouse.&amp;nbsp; The result is then a new event which will fire only when the mouse is in the bounding box, and will produce the larger of it’s X and Y coordinate as it’s value. We can then hook up a listener to print out the values whenever this new event fires.&lt;/P&gt;
&lt;P&gt;But how do we use this to solve the original problem? &lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: green"&gt;/// Compute a running mean and standard deviation over the 
/// input event stream of floating point numbers
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;meanAndStdDev nums = 
    &lt;SPAN style="COLOR: green"&gt;// A function which updates the on-line computation of n, mean and M2
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;newValues (n, mean, M2) x = 
        &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;n' = n+1.
        &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;delta = x - mean
        &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;mean' = mean + delta/n'
        &lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;M2' = M2 + delta*(x - mean')
        (n', mean', M2')
    &lt;SPAN style="COLOR: green"&gt;// The initial vaues of n, mean and M2
    &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;startValues = (0., 0., 0.)
    &lt;SPAN style="COLOR: green"&gt;// The resulting event stream is a scan over the input events 
    &lt;/SPAN&gt;nums 
    |&amp;gt; Event.scan newValues startValues
    |&amp;gt; Event.map (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;(n, mean, M2) &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;(mean, sqrt(M2/(n))))&lt;/PRE&gt;
&lt;P&gt;It’s almost identical to the “on-line” algorithm over sequences! This is one of the important benefits of writing more declarative code using constructs like “scan”.&amp;nbsp; Although the implementations of “scan” over sequences and over events are quite different under the hood – the design pattern of scanning makes sense over both, and is the concept we can program with to tackle the problem at a higher-level.&amp;nbsp; It really makes you feel that we’ve succeeded in expressing the “what” in place of the “how”. &lt;/P&gt;
&lt;P&gt;Here’s what it looks like to use this new function we’ve created:&lt;/P&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: green"&gt;// Create a new event – we would hook up to the stock ticker events if they were available
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;fireNewNum, numEventStream = Event.create&amp;lt;float&amp;gt;()

&lt;SPAN style="COLOR: green"&gt;// Derive a new event that computes the running mean and stddev 
// over the original event stream
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let &lt;/SPAN&gt;stddevEvents = meanAndStdDev numEventStream

&lt;SPAN style="COLOR: green"&gt;// Hook up an event handler to print out the new mean and standard deviation 
&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;stddevEvents |&amp;gt; Event.listen (&lt;SPAN style="COLOR: blue"&gt;fun &lt;/SPAN&gt;(mean, stddev) &lt;SPAN style="COLOR: blue"&gt;-&amp;gt; &lt;/SPAN&gt;printfn &lt;SPAN style="COLOR: maroon"&gt;"Mean = %A, StdDev = %A" &lt;/SPAN&gt;mean stddev)

&lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;fireNewNum 3.
&lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;fireNewNum 7.
&lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;fireNewNum 7.
&lt;SPAN style="COLOR: blue"&gt;do &lt;/SPAN&gt;fireNewNum 19.&lt;/PRE&gt;
&lt;H2&gt;Conclusion&lt;/H2&gt;
&lt;P&gt;This is a fun example that really shows off why it’s so valuable to use higher-level design patterns for programming in the small – like “map”, “average”, “average_by” and “scan”.&amp;nbsp; First class events in F# are a unifying features which allows you to do the same kind of programming you use with sequences and apply it also to events.&amp;nbsp; This is really compelling, because it’s a case where two data sources which are conceptually very similar are often programmed in very different ways – but with higher-level programming models that functional programming and F# provide, you can program against both using the same techniques.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8994678" width="1" height="1"&gt;</content><author><name>LukeH</name><uri>http://blogs.msdn.com/members/LukeH.aspx</uri></author></entry><entry><title>F# September 2008 CTP - Known Issues</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/lukeh/archive/2008/09/17/f-september-2008-ctp-known-issues.aspx" /><id>http://blogs.msdn.com/lukeh/archive/2008/09/17/f-september-2008-ctp-known-issues.aspx</id><published>2008-09-17T19:48:00Z</published><updated>2008-09-17T19:48:00Z</updated><content type="html">&lt;P&gt;We released the F# CTP a few weeks ago, and have been receiving tons of great feedback from F# developers since.&amp;nbsp; Here are some of the common issues which we've been asked about.&amp;nbsp; We'll continue to add on to this list as any new issues are raised.&amp;nbsp; Please continue to send any feedback, suggestions or comments to us at &lt;A href="mailto:fsbugs@microsoft.com" mce_href="mailto:fsbugs@microsoft.com"&gt;fsbugs@microsoft.com&lt;/A&gt;.&lt;/P&gt;
&lt;H1&gt;Known Issues &lt;/H1&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=Posts&amp;amp;sectionid=3786&amp;amp;postid=8955796#1"&gt;Ctrl+. keybinding doesn't invoke View.ShowSmartTag in C# and VB editors&lt;/A&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=Posts&amp;amp;sectionid=3786&amp;amp;postid=8955796#2"&gt;Saving an F# project can fail when 'Save As' is invoked or VB profile is used &lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=Posts&amp;amp;sectionid=3786&amp;amp;postid=8955796#3"&gt;Cannot add a reference to a project in a Solution folder&lt;/A&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=Posts&amp;amp;sectionid=3786&amp;amp;postid=8955796#4"&gt;Cannot add reference from an F# project to a C++/CLI project in Visual Studio&lt;/A&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=Posts&amp;amp;sectionid=3786&amp;amp;postid=8955796#5"&gt;Error message about a missing reference may get 'stuck' in the Error List&amp;nbsp; &lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=Posts&amp;amp;sectionid=3786&amp;amp;postid=8955796#6"&gt;F# on 64bit&lt;/A&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=Posts&amp;amp;sectionid=3786&amp;amp;postid=8955796#7"&gt;Build errors are not reported in the Error List&lt;/A&gt; &lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx?SelectedNavItem=Posts&amp;amp;sectionid=3786&amp;amp;postid=8955796#8"&gt;Dynamically evaluating a quotation which uses the "pown" function fails at runtime&lt;/A&gt; &lt;/LI&gt;&lt;/OL&gt;
&lt;H2&gt;&lt;A title=1 name=1&gt;&lt;/A&gt;1. Ctrl+. keybinding doesn't invoke View.ShowSmartTag in C# and VB editors&lt;/H2&gt;
&lt;P&gt;&lt;EM&gt;&lt;STRONG&gt;Issue&lt;/STRONG&gt;&lt;/EM&gt;: &lt;/P&gt;
&lt;P&gt;The F# CTP uses the ctrl+. keybinding to break execution in the F# Interactive.&amp;nbsp; However, this keybinding is incorrectly applied globally, which prevents it from working in it's standard Visual Studio use of activating an editor SmartTag in the C# and VB editors.&amp;nbsp; The result is that installing the F# CTP prevents this keybinding from working in the C# and VB editors.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;&lt;STRONG&gt;Workaround&lt;/STRONG&gt;&lt;/EM&gt;:&amp;nbsp; &lt;/P&gt;
&lt;P&gt;To set the keybinding for ctrl+. back to it's original binding to the SmartTag, do the following. &lt;BR&gt;In Tools-&amp;gt;Options-&amp;gt;Environment-&amp;gt;Keyboard do the following: &lt;BR&gt;1) Type "View.ShowSmartTag" in the "Show commands containing:" entry field &lt;BR&gt;2) Hold down "ctrl" and press "." (dot) in the "Press shortcut keys" entry field &lt;BR&gt;3) Click "Assign" &lt;/P&gt;
&lt;P&gt;You can optionally re-assign the "OtherContextMenus.FSIConsoleContext.CancelEvaluation" command another keybinding, using similar steps.&amp;nbsp; Alternatively you can use the right-click menu option to cancel evaluation in the F# Interactive when needed.&lt;/P&gt;
&lt;H2&gt;&lt;A title=2 name=2&gt;&lt;/A&gt;2. Saving an F# project can fail when 'Save As' is invoked or VB profile is used&lt;/H2&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;Issue&lt;/EM&gt;&lt;/STRONG&gt;:&lt;/P&gt;
&lt;P&gt;The 'Save As' command in Visual Studio does not work on F# project files in the CTP release.&amp;nbsp; Projects can be saved with the name they were created with, but cannot be saved with a different name.&amp;nbsp; Related to this, if the 'Save new projects when created' option in Visual Studio is turned off, it is not possible to save an F# project after creating it.&amp;nbsp; Note that this setting is off by default in the VB profile, but on in all other Visual Studio profiles.&amp;nbsp; In both cases, an error message saying "The operation could not be completed.&amp;nbsp; No such interface supported" will be raised.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;Workaround&lt;/EM&gt;&lt;/STRONG&gt;:&lt;/P&gt;
&lt;P&gt;In Tools-&amp;gt;Options-&amp;gt;Projects and Solutions-&amp;gt;General ensure that 'Save new projects when created' is checked.&amp;nbsp; To move a project file to another location, save the project and close Visual Studio, then move the project file manually and then reopen it in it's new location.&lt;/P&gt;
&lt;H2&gt;&lt;A title=3 name=3&gt;&lt;/A&gt;3. Cannot add a reference to a project in a Solution folder&lt;/H2&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;Issue&lt;/EM&gt;&lt;/STRONG&gt;: &lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Attempting to add a reference from an F# project to a project which is inside a Solution Folder results in "Object not set to an instance of an object." error message, and fails to add the reference.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;Workaround&lt;/EM&gt;&lt;/STRONG&gt;:&lt;/P&gt;
&lt;P&gt;You can add an assembly reference to the output of the other project's build by browsing to the assembly in the Add Reference... dialog.&amp;nbsp; In some cases, it may be important to pick up the correct version of the referenced assembly depending on the build configuration, in these cases, rules such as the following can be added manually to the .fsproj file:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Reference Include="..\SolutionFolder\Library2\bin\Debug\Library2.dll" Condition ="'$(Configuration)' == 'Debug'" /&amp;gt; &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Reference Include="..\SolutionFolder\Library2\bin\Release\Library2.dll" Condition ="'$(Configuration)' == 'Release'" /&amp;gt;&lt;/P&gt;
&lt;H2&gt;&lt;A title=4 name=4&gt;&lt;/A&gt;4. Cannot add reference from an F# project to a C++/CLI project in Visual Studio&lt;/H2&gt;
&lt;P&gt;&lt;EM&gt;&lt;STRONG&gt;Issue&lt;/STRONG&gt;&lt;/EM&gt;:&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Attempting to add a project reference from an F# project to a C++/CLI project results in "Object not set to an instance of an object." error message, and fails to add the reference.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;&lt;STRONG&gt;Workaround&lt;/STRONG&gt;&lt;/EM&gt;:&amp;nbsp; &lt;/P&gt;
&lt;P&gt;You can add an assembly reference to the output of the C++/CLI build by browsing to the assembly in the Add Reference... dialog.&amp;nbsp; In some cases, it may be important to pick up the correct version of the referenced assembly depending on the build configuration, in these cases, rules such as the following can be added manually to the .fsproj file:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Reference Include="..\ClassLibrary2\bin\Debug\ClassLibrary2.dll" Condition ="'$(Configuration)' == 'Debug'" /&amp;gt; &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Reference Include="..\ClassLibrary2\bin\Release\ClassLibrary2.dll" Condition ="'$(Configuration)' == 'Release'" /&amp;gt;&lt;/P&gt;
&lt;H2&gt;5. Error message about a missing reference may get 'stuck' in the Error List&lt;/H2&gt;
&lt;P&gt;&lt;EM&gt;&lt;STRONG&gt;Issue&lt;/STRONG&gt;&lt;/EM&gt;:&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Adding a project reference to a project which has never been built will result in an error message appearing in the referencing project.&amp;nbsp; This error message may not go away when the referenced project is built.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;&lt;STRONG&gt;Workaround&lt;/STRONG&gt;&lt;/EM&gt;:&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Shutting down and restarting Visual Studio will cause the error message to go away.&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;H2&gt;&lt;A title=6 name=6&gt;&lt;/A&gt;6. F# on 64bit&lt;/H2&gt;
&lt;P&gt;&lt;EM&gt;&lt;STRONG&gt;Issue&lt;/STRONG&gt;&lt;/EM&gt;:&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Broadly speaking, F# applications will work well on 64bit machines and operating systems.&amp;nbsp; However, there are two possible issues to be aware of.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;The F# compiler and interactive are both 32bit processes, and will run in the WoW64 on 64-bit operating systems.&amp;nbsp; This may prevent loading native 64bit code into the F# interactive and may cause registry reads/writes to behave differently than in a true 64bit process.&amp;nbsp; &lt;/LI&gt;
&lt;LI&gt;F# code may be compiled as either 32bit, 64bit, or platform agnostic (AnyCPU).&amp;nbsp; Note that when F# applications are run on 64bit, they use the CLR's 64bit Just-In-Time compiler, which may not do tail call optimization in all cases, possibly resulting in StackOverflowExceptions in 64bit environments that were not seen in 32bit environments. &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;&lt;EM&gt;&lt;STRONG&gt;Workaround&lt;/STRONG&gt;&lt;/EM&gt;:&amp;nbsp; &lt;/P&gt;
&lt;P&gt;It is possible to make F# Interactive load as 64-bit by modifying fsi.exe using corflags.exe. There are details on this .NEt Framework SDK tool at &lt;A href="http://msdn.microsoft.com/en-us/library/ms164699(VS.80).aspx"&gt;http://msdn.microsoft.com/en-us/library/ms164699(VS.80).aspx&lt;/A&gt;.&lt;/P&gt;
&lt;H2&gt;&lt;A title=7 name=7&gt;&lt;/A&gt;7. Build errors are not reported in the Error List&lt;/H2&gt;
&lt;P&gt;&lt;EM&gt;&lt;STRONG&gt;Issue&lt;/STRONG&gt;&lt;/EM&gt;:&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The error list in Visual Studio shows errors reported by the F# background compiler, but does not show errors reported by the F# compiler during an explicit build.&amp;nbsp; These are in most cases the same, so that this is not always an issue.&amp;nbsp; However, if some files in the project are not open, or if an error is reported during generation of the assembly, it may not appear in the error list.&amp;nbsp; Additionally, errors will appear in the error list for any open files, even ones which are not part of the current project.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;&lt;STRONG&gt;Workaround&lt;/STRONG&gt;&lt;/EM&gt;:&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The Output Window in Visual Studio will always show the full results of a build.&lt;/P&gt;
&lt;H2&gt;&lt;A title=8 name=8&gt;&lt;/A&gt;8. Dynamically evaluating a quotation which uses the "pown" function fails at runtime&lt;/H2&gt;
&lt;P&gt;&lt;EM&gt;&lt;STRONG&gt;Issue&lt;/STRONG&gt;&lt;/EM&gt;: &lt;/P&gt;
&lt;P&gt;Attempting to use the LINQ evaluation of a quotation involving the "pown" function will result in a DynamicInvocationNotSupportedException.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;&lt;STRONG&gt;Workaround&lt;/STRONG&gt;&lt;/EM&gt;: &lt;/P&gt;
&lt;P&gt;Consider using the ** exponentiation operator, a custom integer exponentiation function or repeated multiplication instead.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8955796" width="1" height="1"&gt;</content><author><name>LukeH</name><uri>http://blogs.msdn.com/members/LukeH.aspx</uri></author></entry><entry><title>ICFP Programming Contest</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/lukeh/archive/2008/07/10/icfp-programming-contest.aspx" /><id>http://blogs.msdn.com/lukeh/archive/2008/07/10/icfp-programming-contest.aspx</id><published>2008-07-10T10:37:54Z</published><updated>2008-07-10T10:37:54Z</updated><content type="html">&lt;p&gt;This years'&amp;nbsp;installment of the &lt;a href="http://blogs.msdn.com/lukeh/archive/2008/05/05/huffman-coding-with-f.aspx"&gt;ICFP Programming Contest&lt;/a&gt; is coming up this weekend.&amp;nbsp; For those who haven't had the chance to try out this programming contest before, I definitely recommend it.&amp;nbsp; I've done the contest 3 of the last 5 years, and each time has been an amazing experience.&amp;nbsp; This year, we've got a couple of teams here who'll be doing the contest, and we're excited to see what the organizers have in store.&amp;nbsp; &lt;/p&gt; &lt;p&gt;The task for the contest changes quite a bit each year, but tends to incorporate themese like implementing interpreters/compilers for simple languages/runtimes and solving optimization or state-space exploration problems related to these interperpreters or programs written to run on these interpreters.&amp;nbsp; In each of the last two years' contests, some really fun puzzle elements have been incoporated into the contest, along with richer storytelling.&lt;/p&gt; &lt;h4&gt;"Universal Machine" in F#&lt;/h4&gt; &lt;p&gt;Of the years I've done the ICFP programming contest, my favorite so far has been the &lt;a href="http://boundvariable.org/"&gt;2006 contest&lt;/a&gt;.&amp;nbsp; It was truly an inspired creation, and I am rather in awe of the group from CMU who put it together.&amp;nbsp; If you didn't do the contest in 2006, you can still go back to the site and try it out - which I can definitely recommend.&lt;/p&gt; &lt;p&gt;The contest &lt;a href="http://boundvariable.org/task.shtml"&gt;started&lt;/a&gt; seemingly simply - pointing to a &lt;a href="http://boundvariable.org/um-spec.txt"&gt;spec for a virtual machine&lt;/a&gt; (the "UM"), a &lt;a href="http://boundvariable.org/codex.umz"&gt;binary&lt;/a&gt; to run on the virtual machine (the "Codex") and a "decryption key" to use: '(\b.bb)(\v.vv)06FHPVboundvarHRAk'.&amp;nbsp; &lt;/p&gt; &lt;p&gt;Earlier this week, to re-live some of the fun of the 2006 contest, and to get mentally ready for this years contest, I re-implemented the UM, this time in F#.&amp;nbsp; Here's what it looks like (take a look at the spec linked above for an expalanation of what it's doing):&lt;/p&gt;&lt;pre class="code"&gt;#light

&lt;span style="color: rgb(0,0,255)"&gt;open&lt;/span&gt; System
&lt;span style="color: rgb(0,0,255)"&gt;open&lt;/span&gt; System.IO

&lt;span style="color: rgb(0,0,255)"&gt;type&lt;/span&gt; UM(p0 : byte[], input : Stream,  output : Stream) = 
    
    &lt;span style="color: rgb(0,128,0)"&gt;// Read byte[] in as little-endian uint[]
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;let&lt;/span&gt; p0AsUInts = 
        [| &lt;span style="color: rgb(0,0,255)"&gt;for&lt;/span&gt; i &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; 0..4..(p0.Length-4) &lt;span style="color: rgb(0,0,255)"&gt;-&amp;gt;&lt;/span&gt; 
            ((uint32 p0.[i])&amp;lt;&amp;lt;&amp;lt;24) + 
            ((uint32 p0.[i+1])&amp;lt;&amp;lt;&amp;lt;16) + 
            ((uint32 p0.[i+2])&amp;lt;&amp;lt;&amp;lt;8) + 
            ((uint32 p0.[i+3])) |] 
    &lt;span style="color: rgb(0,128,0)"&gt;// The resizable array of memory pages starts with just the input
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;let&lt;/span&gt; mem = ResizeArray.create 1 p0AsUInts
    &lt;span style="color: rgb(0,128,0)"&gt;// The registers are initialized to 0
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;let&lt;/span&gt; reg = [|0u;0u;0u;0u;0u;0u;0u;0u|]

    &lt;span style="color: rgb(0,128,0)"&gt;// The main loop of the interpreter.  Should be *fast*.
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;let&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;rec&lt;/span&gt; cycle finger = 
        &lt;span style="color: rgb(0,0,255)"&gt;let&lt;/span&gt; arr = mem.[0]
        &lt;span style="color: rgb(0,0,255)"&gt;let&lt;/span&gt; op = arr.[finger]
        &lt;span style="color: rgb(0,0,255)"&gt;let&lt;/span&gt; code = op &amp;gt;&amp;gt;&amp;gt; 28
        &lt;span style="color: rgb(0,0,255)"&gt;let&lt;/span&gt; (a,b,c) = (int ((op &amp;gt;&amp;gt;&amp;gt; 6) &amp;amp;&amp;amp;&amp;amp; 0b111u), int ((op &amp;gt;&amp;gt;&amp;gt; 3) &amp;amp;&amp;amp;&amp;amp; 0b111u), int ((op) &amp;amp;&amp;amp;&amp;amp; 0b111u))
        &lt;span style="color: rgb(0,0,255)"&gt;let&lt;/span&gt; (a2, value) = (int (op &amp;gt;&amp;gt;&amp;gt; 25) &amp;amp;&amp;amp;&amp;amp; 0b111, op &amp;amp;&amp;amp;&amp;amp; 0b1111111111111111111111111u)
        &lt;span style="color: rgb(0,0,255)"&gt;match&lt;/span&gt; code &lt;span style="color: rgb(0,0,255)"&gt;with
&lt;/span&gt;        | 0u &lt;span style="color: rgb(0,0,255)"&gt;-&amp;gt;&lt;/span&gt; (&lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; reg.[c] &amp;lt;&amp;gt; 0u &lt;span style="color: rgb(0,0,255)"&gt;then&lt;/span&gt; reg.[a] &amp;lt;- reg.[b]); cycle (finger+1)
        | 1u &lt;span style="color: rgb(0,0,255)"&gt;-&amp;gt;&lt;/span&gt; (reg.[a] &amp;lt;- mem.[int reg.[b]].[int reg.[c]]); cycle (finger+1)
        | 2u &lt;span style="color: rgb(0,0,255)"&gt;-&amp;gt;&lt;/span&gt; (mem.[int reg.[a]].[int reg.[b]] &amp;lt;- reg.[c]); cycle (finger+1)
        | 3u &lt;span style="color: rgb(0,0,255)"&gt;-&amp;gt;&lt;/span&gt; (reg.[a] &amp;lt;- reg.[b] + reg.[c]); cycle (finger+1)
        | 4u &lt;span style="color: rgb(0,0,255)"&gt;-&amp;gt;&lt;/span&gt; (reg.[a] &amp;lt;- reg.[b] * reg.[c]); cycle (finger+1)
        | 5u &lt;span style="color: rgb(0,0,255)"&gt;-&amp;gt;&lt;/span&gt; (reg.[a] &amp;lt;- reg.[b] / reg.[c]); cycle (finger+1)
        | 6u &lt;span style="color: rgb(0,0,255)"&gt;-&amp;gt;&lt;/span&gt; (reg.[a] &amp;lt;- ~~~ (reg.[b] &amp;amp;&amp;amp;&amp;amp; reg.[c])); cycle (finger+1)
        | 7u &lt;span style="color: rgb(0,0,255)"&gt;-&amp;gt;&lt;/span&gt; ()
        | 8u &lt;span style="color: rgb(0,0,255)"&gt;-&amp;gt;&lt;/span&gt; (mem.Add(Array.zero_create (int reg.[c])); reg.[b] &amp;lt;- uint32 (mem.Count - 1)); cycle (finger+1)
        | 9u &lt;span style="color: rgb(0,0,255)"&gt;-&amp;gt;&lt;/span&gt; (mem.[int reg.[c]] &amp;lt;- [||]); cycle (finger+1)
        | 10u &lt;span style="color: rgb(0,0,255)"&gt;-&amp;gt;&lt;/span&gt; (output.WriteByte(byte reg.[c])); cycle (finger+1)
        | 11u &lt;span style="color: rgb(0,0,255)"&gt;-&amp;gt;&lt;/span&gt; (reg.[c] &amp;lt;- uint32 (input.ReadByte() % 255)); cycle (finger+1)
        | 12u &lt;span style="color: rgb(0,0,255)"&gt;-&amp;gt;&lt;/span&gt; (&lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; reg.[b] &amp;lt;&amp;gt; 0u &lt;span style="color: rgb(0,0,255)"&gt;then&lt;/span&gt; mem.[0] &amp;lt;- Array.copy mem.[int reg.[b]]); cycle (int reg.[c])
        | 13u &lt;span style="color: rgb(0,0,255)"&gt;-&amp;gt;&lt;/span&gt; (reg.[a2] &amp;lt;- value); cycle (finger+1)
        | _ &lt;span style="color: rgb(0,0,255)"&gt;-&amp;gt;&lt;/span&gt; failwith &lt;span style="color: rgb(163,21,21)"&gt;"Did not understand %A"&lt;/span&gt; (op, code, a, b, c)
    
    &lt;span style="color: rgb(0,128,0)"&gt;/// Start the Universal Machine running
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;member&lt;/span&gt; this.Run() = 
        cycle 0

&lt;span style="color: rgb(0,0,255)"&gt;let&lt;/span&gt; program = File.ReadAllBytes(&lt;span style="color: rgb(163,21,21)"&gt;"codex.umz"&lt;/span&gt;);
&lt;span style="color: rgb(0,0,255)"&gt;let&lt;/span&gt; ee = UM(program, Console.OpenStandardInput(), Console.OpenStandardOutput())
&lt;span style="color: rgb(0,128,0)"&gt;//Try the following if too much is printed to the screen 
//let ee = UM(program, Console.OpenStandardInput(), new FileStream("umix.um", FileMode.Create))
&lt;/span&gt;ee.Run()&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;h5&gt;Performance&lt;/h5&gt;
&lt;p&gt;This code is doing a lot of bit-level operations in F#.&amp;nbsp; The meat of the code is the tight loop that runs executing the "cycle" function.&amp;nbsp; Since this is the runtime that the provided binary will run on, it needs to be fast.&amp;nbsp; And, fortunately,&amp;nbsp;it is.&amp;nbsp; On my laptop, this loop runs about 15million iterations per second.&amp;nbsp; Of course, there are opportunities to improve on the performance of this code, but this turns out to be fast enough for the problem, and it's convenient that you get this performance profile by default.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h5&gt;That Doesn't Look Very Functional?&lt;/h5&gt;
&lt;p&gt;This code is not particularly 'functional'.&amp;nbsp; But it is totally reasonable F# code.&amp;nbsp; We often talk about F# as a hybrid functional, imperative and OO programming language.&amp;nbsp; This is an example where the problem domain really suggests the use of some imperative programming ideas.&amp;nbsp; The problem defines some global state: the memory, and the registers.&amp;nbsp; Since we're going to be modifying these constantly during the execution of the runtime, it makes sense to use mutable arrays to store the contents.&amp;nbsp; F# makes this nice and easy to do.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h5&gt;Wrapping it up with a little OO&lt;/h5&gt;
&lt;p&gt;As I menionted in a &lt;a href="http://blogs.msdn.com/lukeh/archive/2008/05/05/huffman-coding-with-f.aspx"&gt;previous blog post&lt;/a&gt;, it's really easy to transition between prototyping and component design with F#.&amp;nbsp; The code above wraps up the state and algorithm for the UM in a simple type definition.&amp;nbsp; This provides nice encapsulation and abstraction over the specific binary to run, and the input and output streams to use.&amp;nbsp; And it also wraps up the F# code in a type which could just as easily be consumed from C# or any other .NET langauge. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8715864" width="1" height="1"&gt;</content><author><name>LukeH</name><uri>http://blogs.msdn.com/members/LukeH.aspx</uri></author></entry><entry><title>F# at TechEd Orlando 2008</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/lukeh/archive/2008/06/10/f-at-teched-orlando-2008.aspx" /><id>http://blogs.msdn.com/lukeh/archive/2008/06/10/f-at-teched-orlando-2008.aspx</id><published>2008-06-10T18:30:31Z</published><updated>2008-06-10T18:30:31Z</updated><content type="html">&lt;p&gt;Last week I was down in Orlando for the 2008 US TechEd Developer conference.&amp;nbsp; It was a great conference.&amp;nbsp; This year TechEd was split into two seperate conferences, one for the Developer audience (last week) and another for the IT audience (this week).&amp;nbsp; The result was more of a developer focus for last week's conference than at previous TechEd's, which happens to align the audience really well for those of us talking about particularly developer-focused technologies like the F# and the other .NET languages.&lt;/p&gt; &lt;p&gt;Here are a few of the key F#-related highlights from the event.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Bill Gates talked about F# and Functional Programming in the conference keynote&lt;/strong&gt;:&amp;nbsp; In his &lt;a href="http://www.microsoft.com/winme/0806/33197A/33197A_TechEd_2008_Gates_33197.asx"&gt;last keynote as a full-time Microsoft employee&lt;/a&gt;, Bill Gates talked about a number of technology trends from a developer perspective.&amp;nbsp; Particularly exciting from the F# perspective was Bill's mention of F# along with Visual Basic and C# as programming languages that show the breadth of options developers have today on the Microsoft platform (fast forward to 23:20).&amp;nbsp; Even better, Bill breifly noted the increasing importance of functional programming techniques, in particular alluding back to earlier comments he had made about hardware trending toward multi-core and the need for apps to leverage increased CPU-parallelism.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Bill Gates wants to learn F#&lt;/strong&gt;:&amp;nbsp; At least, that was the title of the mail I was forwarded with a link to an &lt;a href="http://channel9.msdn.com/posts/Dan/Bill-Gates-TechEd-Keynote/"&gt;interview Bill did with Dan Fernandez&lt;/a&gt; after the TechEd keynote :-).&amp;nbsp; Near the end of the interview (fast forward to 8:07), Bill talks about some of the work he'll be doing at the foundation, which (among many other things I'm sure) will include visualizing and manipulating large datasets, and likely wanting to write some custom algorithms for working with this data.&amp;nbsp; He mentions that&amp;nbsp;he has heard that F# can be a great tool for this - and then says he's looking forward to getting time to try it out.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Amanda Laucher did an F# Presentation for "Speaker Idol"&lt;/strong&gt;:&amp;nbsp; &lt;a href="http://www.pandamonial.com/"&gt;Amanda&lt;/a&gt; did a quick 5 minute presentation as part of the Speaker Idol competition at TechEd.&amp;nbsp; Her presentation was a nice demo of using F# for an alogithmic development task - using one of the &lt;a href="http://projecteuler.net/"&gt;Project Euler&lt;/a&gt; problems as an example.&amp;nbsp; She get's extra points for presenting in a custom-made, bright-pink shirt with "F#TW!" printed on it (apparently that is read as "F# For The Win" :-))&amp;nbsp; I'll have to find out if we can get some more of these shirts printed for other F# community members to wear when they are presenting! &lt;/li&gt; &lt;li&gt;&lt;strong&gt;Ted Neward and I presented a breakout session "Busy .NET Developer's Guide to F#"&lt;/strong&gt;:&amp;nbsp; Our session was an introduction to F# focused toward exisiting .NET developers using C# and/or VB.&amp;nbsp; For those who have seen F# presentations before, this one focused less on the flashy demos, and more on the basics of what F# feels like to read, write and execute in Visual Studio and using the F# Interactive.&amp;nbsp; I thought the session went really well.&amp;nbsp; We had a pretty full house (especially for the 8:30AM timeslot!) and got some great questions and discussion after the session.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;C9 Bytes F# video demo&lt;/strong&gt;:&amp;nbsp; I stopped by the Channel 9 filming station to do a &lt;a href="http://channel9.msdn.com/"&gt;quick F# video demo&lt;/a&gt; after the breakout session.&amp;nbsp; The video showed how F# and the F# Interactive can be used with Managed DirectX to do 3D graphing and visualization.&amp;nbsp; This is actually one of the samples we ship as part of the &lt;a href="http://research.microsoft.com/fsharp/release.aspx"&gt;F# download&lt;/a&gt;&amp;nbsp;(you'll need to also install the DirectX SDK if you don't already have it). &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;If you made it out to TechEd this year, I hope you had a great time.&amp;nbsp; If not, hopefully we'll see you at PDC2008 in October.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8590052" width="1" height="1"&gt;</content><author><name>LukeH</name><uri>http://blogs.msdn.com/members/LukeH.aspx</uri></author></entry><entry><title>Huffman Coding with F#</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/lukeh/archive/2008/05/05/huffman-coding-with-f.aspx" /><id>http://blogs.msdn.com/lukeh/archive/2008/05/05/huffman-coding-with-f.aspx</id><published>2008-05-06T05:50:00Z</published><updated>2008-05-06T05:50:00Z</updated><content type="html">&lt;P&gt;I recall my sense of awe when I first wrote a simple compression application using &lt;A href="http://en.wikipedia.org/wiki/Huffman_coding" mce_href="http://en.wikipedia.org/wiki/Huffman_coding"&gt;Huffman Coding&lt;/A&gt; a few years ago for a school assignment.&amp;nbsp; Compression is one of those things that just kind of feels like magic - you get to take something, and make it smaller without losing any information!&amp;nbsp; It's done so often that it now seems commonplace - but, like so many other programming projects, there is something rewarding about writing your own implementation and seeing it actually work.&lt;/P&gt;
&lt;P&gt;When I was in Cambridge a couple weeks ago visiting the Microsft Research-based part of the F# team, I stopped by one of the nice bookstores in Cambridge and ended up picking up a copy of&amp;nbsp;&lt;A href="http://www.amazon.com/Information-Theory-Inference-Learning-Algorithms/dp/0521642981" mce_href="http://www.amazon.com/Information-Theory-Inference-Learning-Algorithms/dp/0521642981"&gt;Information Theory, Inference and Learning Algorithms&lt;/A&gt; by David MacKay - which has been a truly great&amp;nbsp;read so far.&amp;nbsp; When I got to the section on Huffman coding, it reminded me of how much I enjoyed implementing the algorithm a a few years back, that time in C.&amp;nbsp; So I decided I should try again, this time in F#!&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;[ &lt;STRONG&gt;Note&lt;/STRONG&gt;: If you are more interested in F# than in Huffman Coding, feel free to skip to the comments after the code below - where I'll talk about some of the reasons why F# works so well for this kind of application. ]&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;[ &lt;STRONG&gt;Note2&lt;/STRONG&gt;: The code below compiles with the newly-released &lt;A href="http://research.microsoft.com/research/downloads/Details/7ac148a7-149b-4056-aa06-1e6754efd36f/Details.aspx?0sr=d" mce_href="http://research.microsoft.com/research/downloads/Details/7ac148a7-149b-4056-aa06-1e6754efd36f/Details.aspx?0sr=d"&gt;F# 1.9.4&lt;/A&gt;.&amp;nbsp; Go grab&amp;nbsp;it for yourself&amp;nbsp;to try out the code!&amp;nbsp;] &lt;/EM&gt;&lt;/P&gt;
&lt;H4&gt;Compression with Huffman Coding&lt;/H4&gt;
&lt;P&gt;Wikipedia has a great &lt;A href="http://en.wikipedia.org/wiki/Huffman_coding" mce_href="http://en.wikipedia.org/wiki/Huffman_coding"&gt;description of Huffman Coding&lt;/A&gt; - so instead of trying to describe it myself, let me just quote from the Wikipedia topic:&lt;/P&gt;
&lt;H5&gt;Huffman Compression&lt;/H5&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;"In &lt;/EM&gt;&lt;A href="http://en.wikipedia.org/wiki/Computer_science" mce_href="http://en.wikipedia.org/wiki/Computer_science"&gt;&lt;EM&gt;computer science&lt;/EM&gt;&lt;/A&gt;&lt;EM&gt; and &lt;/EM&gt;&lt;A href="http://en.wikipedia.org/wiki/Information_theory" mce_href="http://en.wikipedia.org/wiki/Information_theory"&gt;&lt;EM&gt;information theory&lt;/EM&gt;&lt;/A&gt;&lt;EM&gt;, &lt;B&gt;Huffman coding&lt;/B&gt; is an &lt;/EM&gt;&lt;A href="http://en.wikipedia.org/wiki/Entropy_encoding" mce_href="http://en.wikipedia.org/wiki/Entropy_encoding"&gt;&lt;EM&gt;entropy encoding&lt;/EM&gt;&lt;/A&gt;&lt;EM&gt; &lt;/EM&gt;&lt;A href="http://en.wikipedia.org/wiki/Algorithm" mce_href="http://en.wikipedia.org/wiki/Algorithm"&gt;&lt;EM&gt;algorithm&lt;/EM&gt;&lt;/A&gt;&lt;EM&gt; used for &lt;/EM&gt;&lt;A href="http://en.wikipedia.org/wiki/Lossless_data_compression" mce_href="http://en.wikipedia.org/wiki/Lossless_data_compression"&gt;&lt;EM&gt;lossless data compression&lt;/EM&gt;&lt;/A&gt;&lt;EM&gt;. The term refers to the use of a &lt;/EM&gt;&lt;A href="http://en.wikipedia.org/wiki/Variable-length_code" mce_href="http://en.wikipedia.org/wiki/Variable-length_code"&gt;&lt;EM&gt;variable-length code&lt;/EM&gt;&lt;/A&gt;&lt;EM&gt; table for encoding a source symbol (such as a character in a file) where the variable-length code table has been derived in a particular way based on the estimated probability of occurrence for each possible value of the source symbol."&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;H5&gt;&lt;STRONG&gt;Basic Technique&lt;/STRONG&gt;&lt;/H5&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;"The technique works by creating a &lt;/EM&gt;&lt;A href="http://en.wikipedia.org/wiki/Binary_tree" mce_href="http://en.wikipedia.org/wiki/Binary_tree"&gt;&lt;EM&gt;binary tree&lt;/EM&gt;&lt;/A&gt;&lt;EM&gt; of nodes. These can be stored in a regular &lt;/EM&gt;&lt;A href="http://en.wikipedia.org/wiki/Array" mce_href="http://en.wikipedia.org/wiki/Array"&gt;&lt;EM&gt;array&lt;/EM&gt;&lt;/A&gt;&lt;EM&gt;, the size of which depends on the number of symbols, n. A node can be either a &lt;/EM&gt;&lt;A href="http://en.wikipedia.org/wiki/Leaf_node" mce_href="http://en.wikipedia.org/wiki/Leaf_node"&gt;&lt;EM&gt;leaf node&lt;/EM&gt;&lt;/A&gt;&lt;EM&gt; or an &lt;/EM&gt;&lt;A href="http://en.wikipedia.org/wiki/Internal_node" mce_href="http://en.wikipedia.org/wiki/Internal_node"&gt;&lt;EM&gt;internal node&lt;/EM&gt;&lt;/A&gt;&lt;EM&gt;. Initially, all nodes are leaf nodes, which contain the &lt;B&gt;symbol&lt;/B&gt; itself, the &lt;B&gt;weight&lt;/B&gt; (frequency of appearance) of the symbol and optionally, a link to a &lt;B&gt;parent&lt;/B&gt; node which makes it easy to read the code (in reverse) starting from a leaf node. Internal nodes contain symbol &lt;B&gt;weight&lt;/B&gt;, links to &lt;B&gt;two child nodes&lt;/B&gt; and the optional link to a &lt;B&gt;parent&lt;/B&gt; node. As a common convention, bit '0' represents following the left child and bit '1' represents following the right child. A finished tree has n leaf nodes and n − 1 internal nodes."&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;A Huffman Coder in F#&lt;/H4&gt;&lt;PRE class=code&gt;#light

&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;open&lt;/SPAN&gt; System

&lt;SPAN style="COLOR: rgb(0,128,0)"&gt;/// Huffman coding uses a binary tree whose leaves are the input symbols 
/// and whose internal nodes are the combined expected frequency of all the
/// symbols beneath them.
&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;type&lt;/SPAN&gt; HuffmanTree = 
    | Leaf &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;of&lt;/SPAN&gt; char * float
    | Node &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;of&lt;/SPAN&gt; float * HuffmanTree * HuffmanTree

&lt;SPAN style="COLOR: rgb(0,128,0)"&gt;/// Provides encoding and decoding for strings containing the given symbols and expected frequencies
&lt;/SPAN&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;type&lt;/SPAN&gt; HuffmanCoder(symbols: seq&amp;lt;char&amp;gt;, frequencies : seq&amp;lt;float&amp;gt;) =
   
    &lt;SPAN style="COLOR: rgb(0,128,0)"&gt;/// Builds a list of leafs for a huffman encoding tree from the input frequencies
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; huffmanTreeLeafs =    
        Seq.zip symbols frequencies
        |&amp;gt; Seq.to_list
        |&amp;gt; List.map Leaf
        
    &lt;SPAN style="COLOR: rgb(0,128,0)"&gt;/// Utility function to get the frequency from a huffman encoding tree node
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; frequency node =
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;match&lt;/SPAN&gt; node &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;with
&lt;/SPAN&gt;        | Leaf(_,p) &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;-&amp;gt;&lt;/SPAN&gt; p
        | Node(p,_,_) &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;-&amp;gt;&lt;/SPAN&gt; p    

    &lt;SPAN style="COLOR: rgb(0,128,0)"&gt;/// Builds a huffman encoding tree from a list of root nodes, iterating until a unique root node
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;rec&lt;/SPAN&gt; buildCodeTree roots = 
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;match&lt;/SPAN&gt; roots |&amp;gt; List.sortBy frequency &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;with
&lt;/SPAN&gt;        | [] &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;-&amp;gt;&lt;/SPAN&gt; failwith &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"Cannot build a Huffman Tree for no inputs"&lt;/SPAN&gt; 
        | [node] &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;-&amp;gt;&lt;/SPAN&gt; node
        | least::nextLeast::rest &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;-&amp;gt;&lt;/SPAN&gt; 
                   &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; combinedFrequency = frequency least + frequency nextLeast
                   &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; newNode = Node(combinedFrequency, least, nextLeast)
                   buildCodeTree (newNode::rest)
               
    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; tree = buildCodeTree huffmanTreeLeafs
     
    &lt;SPAN style="COLOR: rgb(0,128,0)"&gt;/// Builds a table of huffman codes for all the leafs in a huffman encoding tree
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; huffmanCodeTable = 
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;rec&lt;/SPAN&gt; huffmanCodes tree = 
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;match&lt;/SPAN&gt; tree &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;with
&lt;/SPAN&gt;            | Leaf (c,_) &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;-&amp;gt;&lt;/SPAN&gt; [(c, [])]
            | Node (_, left, right) &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;-&amp;gt;&lt;/SPAN&gt; 
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; leftCodes = huffmanCodes left |&amp;gt; List.map (&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;fun&lt;/SPAN&gt; (c, code) &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;-&amp;gt;&lt;/SPAN&gt; (c, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;true&lt;/SPAN&gt;::code))
                &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; rightCodes = huffmanCodes right |&amp;gt; List.map (&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;fun&lt;/SPAN&gt; (c, code) &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;-&amp;gt;&lt;/SPAN&gt; (c, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;false&lt;/SPAN&gt;::code))
                List.append leftCodes rightCodes
        huffmanCodes tree 
        |&amp;gt; List.map (&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;fun&lt;/SPAN&gt; (c,code) &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;-&amp;gt;&lt;/SPAN&gt; (c,List.to_array code))
        |&amp;gt; Map.of_list

    &lt;SPAN style="COLOR: rgb(0,128,0)"&gt;/// Encodes a string using the huffman encoding table
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; encode (str:string) = 
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; encodeChar c = 
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;match&lt;/SPAN&gt; huffmanCodeTable |&amp;gt; Map.tryFind c &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;with
&lt;/SPAN&gt;            | Some bits &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;-&amp;gt;&lt;/SPAN&gt; bits
            | None &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;-&amp;gt;&lt;/SPAN&gt; failwith &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"No frequency information provided for character '%A'"&lt;/SPAN&gt; c
        str.ToCharArray()
        |&amp;gt; Array.map encodeChar
        |&amp;gt; Array.concat
       
    
    &lt;SPAN style="COLOR: rgb(0,128,0)"&gt;/// Decodes an array of bits into a string using the huffman encoding tree
&lt;/SPAN&gt;    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; decode bits =
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;rec&lt;/SPAN&gt; decodeInner bitsLeft treeNode result = 
            &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;match&lt;/SPAN&gt; bitsLeft, treeNode &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;with
&lt;/SPAN&gt;            | [] , Node (_,_,_) &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;-&amp;gt;&lt;/SPAN&gt; failwith &lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"Bits provided did not form a complete word"
&lt;/SPAN&gt;            | [] , Leaf (c,_) &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;-&amp;gt;&lt;/SPAN&gt;  (c:: result) |&amp;gt; List.rev |&amp;gt; List.to_array
            | _  , Leaf (c,_) &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;-&amp;gt;&lt;/SPAN&gt; decodeInner bitsLeft tree (c::result)
            | b::rest , Node (_,l,r)  &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;-&amp;gt;&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; b
                                         &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;then&lt;/SPAN&gt; decodeInner rest l result
                                         &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;else&lt;/SPAN&gt; decodeInner rest r result
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; bitsList = Array.to_list bits
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; String (decodeInner bitsList tree [])
                 
    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;member&lt;/SPAN&gt; coder.Encode source = encode source
    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;member&lt;/SPAN&gt; coder.Decode source = decode source&lt;/PRE&gt;
&lt;H5&gt;Pattern Matching &lt;/H5&gt;
&lt;P&gt;Pattern matching is one of the basic but very powerful features of F#.&amp;nbsp; Using pattern matching allows code to be succinct while at the same time very clear about it's behaviour.&amp;nbsp; Just about every function in the code above uses pattern matching - which is typical of a lot of F# code.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;In simple cases, such as in "huffmanCodes" above, pattern matching makes it easy to switch on the possible cases of a union datastructure.&amp;nbsp; &lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;match&lt;/SPAN&gt; tree &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;with
&lt;/SPAN&gt;| Leaf (c,_) &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;-&amp;gt;&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,128,0)"&gt;//...&lt;/SPAN&gt;
| Node (_, left, right) &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;-&amp;gt;&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,128,0)"&gt;//...&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;P&gt;In more complex cases like "decodeInner" above, pattern matching helps to guide your code. You list each shape of input that you know how to handle, and the leaf nodes of the pattern you matched indicate the data needed to define the&amp;nbsp;behaviour of that case.&amp;nbsp;&amp;nbsp;Then the compiler kindly tells you which cases you haven't covered. When I wrote this function originally, I was missing the first case, and got this helpful compiler warning:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;PRE class=code&gt;Warning: Incomplete pattern matches on this expression. The value '([],Node (_, _, _))' will not be matched &lt;/PRE&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Which was exactly right - this particular input indicates that the user provided illegal inputs!&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;H5&gt;Pipelining&lt;/H5&gt;
&lt;P&gt;Pipelining is&amp;nbsp;a nice way to declaratively describe a series of&amp;nbsp;operations to perform on an input.&amp;nbsp; It's philosophically just like&amp;nbsp;pipelining in a command shell - take the input data from the left and pass it as input to the function on the right.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Because the F# libraries provide a good collection of primitive operations to perform on your data, it's easy to describe a transformation as a pipeline of data through a sequence of these operations.&amp;nbsp; For example, you can filter, project, collapse, zip, and re-package data easily and declaratively.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;H5&gt;Collections&lt;/H5&gt;
&lt;P&gt;The code uses the 4 common F#/.NET collections:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;EM&gt;F# "List"&lt;/EM&gt;: Immutable linked list used for recursive algorithms which walk across a list 
&lt;LI&gt;F# "Map": Immutable dictionary used to store the codes for each symbols 
&lt;LI&gt;&lt;EM&gt;F# "Seq" = .NET "IEnumerable"&lt;/EM&gt;:&amp;nbsp; Primitive collection interface, used for the inputs 
&lt;LI&gt;&lt;EM&gt;.NET "Array"&lt;/EM&gt;: Basic typed arrays used as the output of the encoding &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Note that it is easy and common to switch between these collections as needed, using functions like "List.to_array" and "Map.of_list".&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;H5&gt;"It's a .NET component!" a.k.a. "The Slickness"&lt;/H5&gt;
&lt;P&gt;When I wrote this code, I started out in "experimentation" mode. I just wrote a bunch of small functions at the top level and used F# Interactive to execute them as I went. But once I had something that seemed to work, I wanted to wrap it up in a class that could encapsulate all the functionality, and provide a nice .NET interface. Here's what I did:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;DIV&gt;Tab everything in one level&lt;/DIV&gt;
&lt;LI&gt;
&lt;DIV&gt;Wrap the code in:&lt;BR&gt;&lt;BR&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;type&lt;/SPAN&gt; HuffmanCoder(symbols : seq&amp;lt;char&amp;gt;, frequencies : seq&amp;lt;float&amp;gt;) = &lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;    &lt;FONT color=#008040&gt;// All the code goes here...&lt;BR&gt;&lt;/FONT&gt;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;member&lt;/SPAN&gt; coder.Encode source = encode source&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;member&lt;/SPAN&gt; coder.Decode source = decode source&lt;/PRE&gt;&lt;/DIV&gt;&lt;PRE&gt;&lt;/PRE&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;I can't really understate how amazing this is.&amp;nbsp; In F#, it is super-simple to smoothly transition from experimentation coding to component design coding.&amp;nbsp; This is something that F# can manage because it is a hybrid functional/OO language intergated carefully into .NET.&amp;nbsp; And because of this, it is really easy to build components of a larger .NET system in F#.&amp;nbsp;&amp;nbsp;I heard this referred to once as "the slickness" of functional OO coding in F#, and I like that term, because whenever I do this it just feels so slick. :-)&lt;/P&gt;
&lt;P&gt;In case you are curious, here's what it looks like from C#:&lt;/P&gt;&lt;PRE class=code&gt;    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;HuffmanCoder
&lt;/SPAN&gt;    {
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; HuffmanCoder(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;char&lt;/SPAN&gt;&amp;gt; symbols, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;IEnumerable&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;double&lt;/SPAN&gt;&amp;gt; frequencies);

        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt; Decode(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;bool&lt;/SPAN&gt;[] source);
        &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;bool&lt;/SPAN&gt;[] Encode(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;string&lt;/SPAN&gt; source);
    }&lt;/PRE&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;
&lt;H4&gt;Summary&lt;/H4&gt;
&lt;P&gt;I found this code to be a good example of some of the things I&amp;nbsp;really like about F#.&amp;nbsp; The algorithmic nature of the code lends itself well to F#'s syntax and programming style.&amp;nbsp; You can start off just writing a bunch of simple, composable&amp;nbsp;functions, each just a half dozen lines of pattern matching and pipelining.&amp;nbsp; As you are doing this, you can use the F# Interactive to experiment with the code and the algorithms&amp;nbsp;as you evolve them into the right functionality.&amp;nbsp; Then when they are working, you can smoothly wrap them up into a .NET component and expose it off to the rest of your .NET consumers.&lt;/P&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=8461981" width="1" height="1"&gt;</content><author><name>LukeH</name><uri>http://blogs.msdn.com/members/LukeH.aspx</uri></author></entry><entry><title>F# Session at TechEd Israel</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/lukeh/archive/2008/04/14/f-session-at-teched-israel.aspx" /><id>http://blogs.msdn.com/lukeh/archive/2008/04/14/f-session-at-teched-israel.aspx</id><published>2008-04-14T16:58:58Z</published><updated>2008-04-14T16:58:58Z</updated><content type="html">&lt;p&gt;I've had the opportunity to do a lot of F# presentations recently, which has been really great.&amp;nbsp; Over the last few months, I've done presentations at the &lt;a href="http://www.microsoft.com/presspass/features/2008/mar08/03-13FinDev.mspx"&gt;Financial Services Developer Conference&lt;/a&gt; in New York, at the &lt;a href="http://www.langnetsymposium.com/"&gt;Lang.NET&lt;/a&gt; conference in Redmond, and at a few internal "brown bag"s for teams in Microsoft.&lt;/p&gt; &lt;p&gt;Most recently though, I was in Israel last week for &lt;a href="http://www.microsoft.com/israel/techedevent/index.aspx"&gt;TechEd Israel&lt;/a&gt; 2008 - a great 3-day conference with more than 3000 attendees, held in sunny &lt;a href="http://en.wikipedia.org/wiki/Eilat"&gt;Eilat&lt;/a&gt;, Israel.&amp;nbsp; I&amp;nbsp;presented an "Introduction to F#" session at the conference, which drew a packed&amp;nbsp;room and&amp;nbsp;some great questions and discussion during and after the talk.&lt;/p&gt; &lt;p&gt;Here are the slides and demo I presented for the TechEd Israel session:&lt;/p&gt; &lt;p&gt;&lt;a title="An Introduction to F#" href="http://www.box.net/shared/7htj6cdgkk"&gt;&lt;img border="0" alt="File icon" align="absMiddle" src="http://www.box.net/thumbs/24x24/application/ppt_file.gif" width="24" height="24"&gt;Dev341.pptx&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a title="F# DirectX Demo" href="http://www.box.net/shared/osqosq9c8c"&gt;&lt;img border="0" alt="File icon" align="absMiddle" src="http://www.box.net/thumbs/24x24/default_file.gif" width="24" height="24"&gt;FSharpDirectX.zip&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;img id="ctl00_ContentPlaceHolder1_extImage" class="thumbnail" alt="FSharp" src="http://visualstudiogallery.com/ExtensionImage.aspx?id=c70bfddf-b6a1-407c-b010-3409e334bb00" width="193" height="160"&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8392711" width="1" height="1"&gt;</content><author><name>LukeH</name><uri>http://blogs.msdn.com/members/LukeH.aspx</uri></author></entry><entry><title>F#</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/lukeh/archive/2007/11/14/f.aspx" /><id>http://blogs.msdn.com/lukeh/archive/2007/11/14/f.aspx</id><published>2007-11-15T02:57:32Z</published><updated>2007-11-15T02:57:32Z</updated><content type="html">&lt;p&gt;A few weeks back, Soma &lt;a href="http://blogs.msdn.com/somasegar/archive/2007/10/17/f-a-functional-programming-language.aspx"&gt;blogged&lt;/a&gt; about an increased investment by the Microsoft Developer Division in the &lt;a href="http://research.microsoft.com/fsharp/fsharp.aspx"&gt;F# language&lt;/a&gt;.&amp;nbsp; Part of this increased investment has been the creation of a small team in Redmond to work with F#'s creator Don Syme to bring F# into the set of first class languages supported on .NET.&amp;nbsp; This provided a great opportunity for me to become one of the early members of this Redmond based F# team.&amp;nbsp; So, as of a few weeks ago, I've traded in my C# Compiler PM role for the newly created F# PM job!&lt;/p&gt; &lt;p&gt;As you can probably tell from some of my &lt;a href="http://blogs.msdn.com/lukeh/archive/2007/08/19/monadic-parser-combinators-using-c-3-0.aspx"&gt;previous&lt;/a&gt; &lt;a href="http://blogs.msdn.com/lukeh/archive/2007/03/31/in-memory-query-with-c-2-0-and-c-3-0.aspx"&gt;blog&lt;/a&gt; &lt;a href="http://blogs.msdn.com/lukeh/archive/2007/10/01/taking-linq-to-objects-to-extremes-a-fully-linqified-raytracer.aspx"&gt;posts&lt;/a&gt;, I have a lot of interest in functional programming with .NET.&amp;nbsp; This makes F# is a naturally exciting language for me to be involved in.&amp;nbsp; F# provides a language in which functional programming is easy and expressive, while at the same time practical and well-connected to the underlying .NET type-system and programming model.&amp;nbsp; A exciting language for the .NET platform indeed!&lt;/p&gt; &lt;h4&gt;Sample F# Code - Mandelbrot&lt;/h4&gt; &lt;p&gt;Here's a little example piece of F# code to hopefully pique your interest to learn more about the language.&lt;/p&gt;&lt;pre class="code"&gt;#light 
&lt;span style="color: rgb(0,0,255)"&gt;open&lt;/span&gt; Microsoft.FSharp.Math
&lt;span style="color: rgb(0,0,255)"&gt;open&lt;/span&gt; System

&lt;span style="color: rgb(0,0,255)"&gt;let&lt;/span&gt; maxIteration = 100

&lt;span style="color: rgb(0,0,255)"&gt;let&lt;/span&gt; modSquared (c : Complex) = c.r * c.r + c.i * c.i

&lt;span style="color: rgb(0,0,255)"&gt;type&lt;/span&gt; MandelbrotResult = 
    | DidNotEscape
    | Escaped &lt;span style="color: rgb(0,0,255)"&gt;of&lt;/span&gt; int
    
&lt;span style="color: rgb(0,0,255)"&gt;let&lt;/span&gt; mandelbrot c = 
    &lt;span style="color: rgb(0,0,255)"&gt;let&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;rec&lt;/span&gt; mandelbrotInner z iterations = 
        &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt;(modSquared z &amp;gt;= 4.0)
            &lt;span style="color: rgb(0,0,255)"&gt;then&lt;/span&gt; Escaped iterations
        &lt;span style="color: rgb(0,0,255)"&gt;elif&lt;/span&gt; iterations = maxIteration
            &lt;span style="color: rgb(0,0,255)"&gt;then&lt;/span&gt; DidNotEscape
        &lt;span style="color: rgb(0,0,255)"&gt;else&lt;/span&gt; mandelbrotInner ((z * z) + c) (iterations + 1)
    mandelbrotInner c 0

&lt;span style="color: rgb(0,0,255)"&gt;for&lt;/span&gt; y &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; [-1.0..0.1..1.0] &lt;span style="color: rgb(0,0,255)"&gt;do
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;for&lt;/span&gt; x &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; [-2.0..0.05..1.0] &lt;span style="color: rgb(0,0,255)"&gt;do
&lt;/span&gt;        &lt;span style="color: rgb(0,0,255)"&gt;match&lt;/span&gt; mandelbrot (Complex.Create (x, y)) &lt;span style="color: rgb(0,0,255)"&gt;with
&lt;/span&gt;        | DidNotEscape &lt;span style="color: rgb(0,0,255)"&gt;-&amp;gt;&lt;/span&gt; Console.Write &lt;span style="color: rgb(163,21,21)"&gt;"#"
&lt;/span&gt;        | Escaped _ &lt;span style="color: rgb(0,0,255)"&gt;-&amp;gt;&lt;/span&gt; Console.Write &lt;span style="color: rgb(163,21,21)"&gt;" "
&lt;/span&gt;    Console.WriteLine () &lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;h5&gt;&lt;strong&gt;Let&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;The &lt;tt&gt;let&lt;/tt&gt; keyword is used to declare a new variable or function.&amp;nbsp; Note in particular the similarities between the declaration of &lt;tt&gt;maxIterations&lt;/tt&gt; and &lt;tt&gt;modSquared&lt;/tt&gt;.&amp;nbsp; Functions are treated much the same as values of any other type throughout F#.&amp;nbsp; 
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Let can be used both at the top level and also inside function definitions to declare a local variable or function.&amp;nbsp; For example, the &lt;tt&gt;mandelbrot&lt;/tt&gt; function uses a local function &lt;tt&gt;mandelbrotInner&lt;/tt&gt; which computes the result, and simply calls it with the initial values.&amp;nbsp; Note also that &lt;tt&gt;mandelInner&lt;/tt&gt; refers to the parameter &lt;tt&gt;c&lt;/tt&gt; passed to the &lt;tt&gt;mandelbrot&lt;/tt&gt; function - local functions are true closures.&lt;/p&gt;
&lt;p&gt;Recursive function can be defined using &lt;tt&gt;let rec&lt;/tt&gt;.&lt;/p&gt;
&lt;h5&gt;&lt;strong&gt;Types&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;F# is built on the .NET type system, and provides access to any type defined in a .NET assembly.&amp;nbsp; Types can also be defined in F# using the keyword &lt;tt&gt;type&lt;/tt&gt;.&amp;nbsp; There are many kinds of types that can be created in F#, for example, standard .NET types such as classes and interfaces can be defined, but F# also supports types such as records and discriminated unions.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;As an example of discrimated unions, in the code above, &lt;tt&gt;MandelbrotResult&lt;/tt&gt; is defined to be a type whose values are either &lt;tt&gt;DidNotEscape&lt;/tt&gt; or are &lt;tt&gt;Escaped&lt;/tt&gt; with an integer.&amp;nbsp; This accurately captures the &lt;a href="http://en.wikipedia.org/wiki/Mandelbrot_set#Formal_definition"&gt;mathematical definition&lt;/a&gt; of the mandelbrot set, which is defined in terms of points in the complex plane either escaping to infinity after a certain number of iterations, or remaining within a bounded region.&lt;/p&gt;
&lt;h5&gt;&lt;strong&gt;Terse Syntax&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;One of the most striking features of F#&amp;nbsp;code is that it is very terse -&amp;nbsp;ideas can typically be expressed&amp;nbsp;with a small amount of code.&amp;nbsp; There are a few significant language features which contribute to this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Type Inference&lt;/em&gt;: F# is strongly typed, like C#, but instead of having to declare the type of variables, parameters and return types, F# uses type inference to determine these automatically.&amp;nbsp; When the types cannot be inferred, type annotations can be supplied in the code, such as in the definition of the &lt;tt&gt;modSquared&lt;/tt&gt; function above. 
&lt;li&gt;&lt;em&gt;#light&lt;/em&gt;: The #light directive in F# allows code to omit &lt;tt&gt;begin&lt;/tt&gt;...&lt;tt&gt;end&lt;/tt&gt; keywords and some other tokens, and instead relies on indentation to indicate nesting.&amp;nbsp; This is similar to languages like Python, and enables the same kind of syntactic lightness that programs in these languages enjoy. 
&lt;li&gt;&lt;em&gt;Expressions&lt;/em&gt;: F# programs are built out of expressions, which can be composed very simply.&amp;nbsp;For example,&amp;nbsp;&lt;tt&gt;if&lt;/tt&gt; is an expression in F#, as opposed to in C# where it is a statement.&amp;nbsp; This&amp;nbsp;can make code simpler, while also&amp;nbsp;enabling a high degree of flexibility.&lt;/li&gt;&lt;/ol&gt;
&lt;h5&gt;&lt;strong&gt;Libraries&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;F# code can use all of the exisiting .NET libraries, such as the &lt;tt&gt;Console&lt;/tt&gt; class used in the code above.&amp;nbsp; But F# also has access to a rich set of F# libraries, providing types that are well suited to functional programming and F# in particular.&amp;nbsp; A few notable libraries:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Math&lt;/em&gt;:&amp;nbsp; One very useful example is the F# math libraries, representing datatypes such as &lt;tt&gt;Vector&lt;/tt&gt;, &lt;tt&gt;Matrix&lt;/tt&gt;, and &lt;tt&gt;BigNum&lt;/tt&gt;, as well as the &lt;tt&gt;Complex&lt;/tt&gt; numbers used in the code above. 
&lt;li&gt;&lt;em&gt;Collections&lt;/em&gt;:&amp;nbsp; The standard .NET Framework collections can be used from F#, but there is also a fully-featured set of functional collections, including the ubiquotous immutable linked list (&lt;tt&gt;List&amp;lt;A&amp;gt;&lt;/tt&gt;), an efficient immutable set built on binary trees (&lt;tt&gt;Set&amp;lt;A&amp;gt;&lt;/tt&gt;) and an immutable dictionary (&lt;tt&gt;Map&amp;lt;Key,A&amp;gt;&lt;/tt&gt;) 
&lt;li&gt;&lt;em&gt;Control&lt;/em&gt;:&amp;nbsp; High-level control structures, such as compositional eventing (&lt;tt&gt;IEvent&amp;lt;A&amp;gt;&lt;/tt&gt;), laziness (&lt;tt&gt;Lazy&amp;lt;A&amp;gt;&lt;/tt&gt;) and most importantly, asynchronous programming primitives (&lt;tt&gt;ASync&amp;lt;A&amp;gt;&lt;/tt&gt;).&amp;nbsp; The last of these in particular is a very exciting feature of F# for multi-threaded programming.&lt;/li&gt;&lt;/ol&gt;
&lt;h5&gt;&lt;strong&gt;Interactive&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;F# comes with an "F# Interactive" toolwindow for Visual Studio, and also a command line interactive shell (fsi.exe).&amp;nbsp; These are tremendously useful for protyping and exploring, and can also be used as a testbed while working on larger projects.&amp;nbsp; As an example (see screenshot below) the code above can be pasted into an interactive shell to execute immediately.&amp;nbsp; If you want to make changes, just edit the code and paste into the interactive prompt again to run the new version.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/F_E1E9/MandelbrotInInteractive%5B20%5D.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="972" src="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/F_E1E9/MandelbrotInInteractive_thumb%5B14%5D.jpg" width="537" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h4&gt;Summary&lt;/h4&gt;
&lt;p&gt;Now that I'm working full-time on F#, you can expect to see more blogs posts here about F# in the future.&amp;nbsp; If you want to try out the code above, or any of the other great F# samples that are floating around the web, go to &lt;a href="http://research.microsoft.com/fsharp/release.aspx"&gt;http://research.microsoft.com/fsharp/release.aspx&lt;/a&gt; and grab the most recent .msi download of the current Microsoft Research release of F#.&lt;/p&gt;
&lt;p&gt;&lt;a title="mandelbrot.fs" href="http://www.box.net/shared/134o4dmxm5"&gt;&lt;img height="24" alt="File icon" src="http://www.box.net/thumbs/24x24/default_file.gif" width="24" align="absMiddle" border="0"&gt;mandelbrot.fs&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6232838" width="1" height="1"&gt;</content><author><name>LukeH</name><uri>http://blogs.msdn.com/members/LukeH.aspx</uri></author></entry><entry><title>Taking LINQ to Objects to Extremes: A fully LINQified RayTracer</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/lukeh/archive/2007/10/01/taking-linq-to-objects-to-extremes-a-fully-linqified-raytracer.aspx" /><id>http://blogs.msdn.com/lukeh/archive/2007/10/01/taking-linq-to-objects-to-extremes-a-fully-linqified-raytracer.aspx</id><published>2007-10-02T05:34:00Z</published><updated>2007-10-02T05:34:00Z</updated><content type="html">&lt;P&gt;Not too long ago I blogged about a &lt;A href="http://blogs.msdn.com/lukeh/archive/2007/04/03/a-ray-tracer-in-c-3-0.aspx" mce_href="http://blogs.msdn.com/lukeh/archive/2007/04/03/a-ray-tracer-in-c-3-0.aspx"&gt;C# raytracer&lt;/A&gt; which took advantage of a lot of C#3.0 language constructs.&amp;nbsp;&amp;nbsp;However, you may have noticed that it did not actually use LINQ query expressions all that much.&amp;nbsp; Well, after discussing this with a coworker on the &lt;A href="http://msdn.microsoft.com/msdnmag/issues/07/10/PLINQ/default.aspx" mce_href="http://msdn.microsoft.com/msdnmag/issues/07/10/PLINQ/default.aspx"&gt;PLINQ&lt;/A&gt;&amp;nbsp;team at lunch one day - I was convinced that it should be possible to express the logic of the raytracer in a LINQ to Objects query.&amp;nbsp; The result is below - a single 60-line LINQ query which captures the complete raytracing algorithm.&lt;/P&gt;
&lt;P&gt;[&lt;STRONG&gt;&lt;EM&gt;DISCLAIMER&lt;/EM&gt;&lt;/STRONG&gt;:&amp;nbsp; I am by no means suggesting it's a good idea to write code like this.&amp;nbsp; Do so only at your own risk!&amp;nbsp; Just as you *could* write your entire application in one method body, or decide to replace all if statements with virtual method dispatches, doing what I show below is a clear abuse of this language construct.&amp;nbsp; But it's an interesting example to show that there is a lot of expresiveness available in C#3.0 query expressions.]&lt;/P&gt;
&lt;H4&gt;One Really Big Query Expression!&lt;/H4&gt;&lt;PRE class=code&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; pixelsQuery =
    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;from&lt;/SPAN&gt; y &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;in&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Enumerable&lt;/SPAN&gt;.Range(0, screenHeight)
    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; recenterY = -(y - (screenHeight / 2.0)) / (2.0 * screenHeight)
    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;select&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;from&lt;/SPAN&gt; x &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;in&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Enumerable&lt;/SPAN&gt;.Range(0, screenWidth)
           &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; recenterX = (x - (screenWidth / 2.0)) / (2.0 * screenWidth)
           &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; point = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Vector&lt;/SPAN&gt;.Norm(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Vector&lt;/SPAN&gt;.Plus(scene.Camera.Forward, &lt;BR&gt;                                               &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Vector&lt;/SPAN&gt;.Plus(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Vector&lt;/SPAN&gt;.Times(recenterX, scene.Camera.Right),
                                                           &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Vector&lt;/SPAN&gt;.Times(recenterY, scene.Camera.Up))))
           &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; ray = &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Ray&lt;/SPAN&gt; { Start = scene.Camera.Pos, Dir = point }
           &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; computeTraceRay = (&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Func&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Func&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;TraceRayArgs&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Color&lt;/SPAN&gt;&amp;gt;, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Func&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;TraceRayArgs&lt;/SPAN&gt;, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Color&lt;/SPAN&gt;&amp;gt;&amp;gt;)
            (f =&amp;gt; traceRayArgs =&amp;gt;
             (&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;from&lt;/SPAN&gt; isect &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;in
&lt;/SPAN&gt;                  &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;from&lt;/SPAN&gt; thing &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;in&lt;/SPAN&gt; traceRayArgs.Scene.Things
                  &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;select&lt;/SPAN&gt; thing.Intersect(traceRayArgs.Ray)
              &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;where&lt;/SPAN&gt; isect != &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;null
&lt;/SPAN&gt;              &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;orderby&lt;/SPAN&gt; isect.Dist
              &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; d = isect.Ray.Dir
              &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; pos = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Vector&lt;/SPAN&gt;.Plus(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Vector&lt;/SPAN&gt;.Times(isect.Dist, isect.Ray.Dir), isect.Ray.Start)
              &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; normal = isect.Thing.Normal(pos)
              &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; reflectDir = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Vector&lt;/SPAN&gt;.Minus(d, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Vector&lt;/SPAN&gt;.Times(2 * &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Vector&lt;/SPAN&gt;.Dot(normal, d), normal))
              &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; naturalColors = &lt;BR&gt;                  &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;from&lt;/SPAN&gt; light &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;in&lt;/SPAN&gt; traceRayArgs.Scene.Lights
                  &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; ldis = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Vector&lt;/SPAN&gt;.Minus(light.Pos, pos)
                  &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; livec = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Vector&lt;/SPAN&gt;.Norm(ldis)
                  &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; testRay = &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Ray&lt;/SPAN&gt; { Start = pos, Dir = livec }
                  &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; testIsects = &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;from&lt;/SPAN&gt; inter &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;in
&lt;/SPAN&gt;                                       &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;from&lt;/SPAN&gt; thing &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;in&lt;/SPAN&gt; traceRayArgs.Scene.Things
                                       &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;select&lt;/SPAN&gt; thing.Intersect(testRay)
                                   &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;where&lt;/SPAN&gt; inter != &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;null
&lt;/SPAN&gt;                                   &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;orderby&lt;/SPAN&gt; inter.Dist
                                   &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;select&lt;/SPAN&gt; inter
                  &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; testIsect = testIsects.FirstOrDefault()
                  &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; neatIsect = testIsect == &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;null&lt;/SPAN&gt; ? 0 : testIsect.Dist
                  &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; isInShadow = !((neatIsect &amp;gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Vector&lt;/SPAN&gt;.Mag(ldis)) || (neatIsect == 0))
                  &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;where&lt;/SPAN&gt; !isInShadow
                  &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; illum = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Vector&lt;/SPAN&gt;.Dot(livec, normal)
                  &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; lcolor = illum &amp;gt; 0 ? &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Color&lt;/SPAN&gt;.Times(illum, light.Color) : &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Color&lt;/SPAN&gt;.Make(0, 0, 0)
                  &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; specular = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Vector&lt;/SPAN&gt;.Dot(livec, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Vector&lt;/SPAN&gt;.Norm(reflectDir))
                  &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; scolor = specular &amp;gt; 0 
                               ? &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Color&lt;/SPAN&gt;.Times(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Math&lt;/SPAN&gt;.Pow(specular, isect.Thing.Surface.Roughness), light.Color) 
                               : &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Color&lt;/SPAN&gt;.Make(0, 0, 0)
                  &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;select&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Color&lt;/SPAN&gt;.Plus(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Color&lt;/SPAN&gt;.Times(isect.Thing.Surface.Diffuse(pos), lcolor),
                                    &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Color&lt;/SPAN&gt;.Times(isect.Thing.Surface.Specular(pos), scolor))
              &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; reflectPos = &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Vector&lt;/SPAN&gt;.Plus(pos, &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Vector&lt;/SPAN&gt;.Times(.001, reflectDir))
              &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; reflectColor = &lt;BR&gt;                  traceRayArgs.Depth &amp;gt;= MaxDepth
                  ? &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Color&lt;/SPAN&gt;.Make(.5, .5, .5)
                  : &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Color&lt;/SPAN&gt;.Times(isect.Thing.Surface.Reflect(reflectPos), 
                                f(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;TraceRayArgs&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Ray&lt;/SPAN&gt; { Start = reflectPos, Dir = reflectDir }, 
                                                   traceRayArgs.Scene, &lt;BR&gt;                                                   traceRayArgs.Depth + 1)))
              &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;select&lt;/SPAN&gt; naturalColors.Aggregate(reflectColor, (color, natColor) =&amp;gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Color&lt;/SPAN&gt;.Plus(color, natColor)))&lt;BR&gt;                                  .DefaultIfEmpty(&lt;SPAN style="COLOR: rgb(43,145,175)"&gt;Color&lt;/SPAN&gt;.Background).First())
           &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;let&lt;/SPAN&gt; traceRay = Y(computeTraceRay)
           &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;select&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; { X = x, Y = y, Color = traceRay(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: rgb(43,145,175)"&gt;TraceRayArgs&lt;/SPAN&gt;(ray, scene, 0)) };

&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;foreach&lt;/SPAN&gt; (&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; row &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;in&lt;/SPAN&gt; pixelsQuery)
    &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;foreach&lt;/SPAN&gt; (&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;var&lt;/SPAN&gt; pixel &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;in&lt;/SPAN&gt; row)
        setPixel(pixel.X, pixel.Y, pixel.Color.ToDrawingColor());&lt;/PRE&gt;
&lt;H5&gt;Let Expressions&lt;/H5&gt;
&lt;P&gt;"let" query clauses allow you to introduce a variable into scope which can be used by the following query clauses.&amp;nbsp; Similar to local variables in a method body, this gives you a way to avoid evaluating a common expression multiple times by storing it in a variable.&amp;nbsp; This can be very useful even in much simpler queries.&amp;nbsp; Of course, in the query above - let is absolutely critical.&lt;/P&gt;
&lt;H5&gt;Recursion&lt;/H5&gt;
&lt;P&gt;A raytracer is inhenertly recursive - whenever a ray hits a reflective or transparent surface, new rays have to be cast.&amp;nbsp; Thus&amp;nbsp;the query that expreses the raytracer needs to be recursive.&amp;nbsp; But the let clause&amp;nbsp;doesn't support&amp;nbsp;declaring recursive functions.&amp;nbsp;&amp;nbsp;Not to let that stop us (as it really should!) - we can use the &lt;A href="http://en.wikipedia.org/wiki/Y_combinator" mce_href="http://en.wikipedia.org/wiki/Y_combinator"&gt;Y combinator&lt;/A&gt; to introduce recursion by hand.&amp;nbsp; Mads wrote a very detailed description of the &lt;A href="http://blogs.msdn.com/madst/archive/2007/05/11/recursive-lambda-expressions.aspx" mce_href="http://blogs.msdn.com/madst/archive/2007/05/11/recursive-lambda-expressions.aspx"&gt;recursive lambda expressions in C#&lt;/A&gt; recently - and the code example above uses my personal implementation of some of the same ideas he describes.&amp;nbsp; &lt;/P&gt;
&lt;H5&gt;Expression-based control structures&lt;/H5&gt;
&lt;P&gt;&lt;A href="http://11011.net/software/vspaste" mce_href="http://11011.net/software/vspaste"&gt;&lt;/A&gt;When you are trying to write things in a single query expression - you don't have the luxury of using any statements.&amp;nbsp; Since most of the C# control structures are &amp;nbsp;statement based (if, switch, for, while, etc.) - this can make things a little trickier.&amp;nbsp; One really valauble expression-based control structure is the ternary operator ( x ? y : z ).&amp;nbsp; This is used in a couple of places above to provide the necessary branching logic.&amp;nbsp; The rest of the control structuring is accomplished with LINQ Standard Query Operators - Select, SelectMany, Where, OrderBy, Aggregate and DefaultIfEmpty.&amp;nbsp; As functional programmers have shown for years, the expressiveness of these very general list processing operations is impressive.&lt;/P&gt;
&lt;H4&gt;Conclusion&lt;/H4&gt;
&lt;P&gt;In case you had any doubts - hopefully this convinces you that C#3.0 Query Expressions are really a very expressive language construct.&amp;nbsp; Of course -&amp;nbsp;this expressiveness is probably best used in&amp;nbsp;more moderation than shown here!&lt;/P&gt;
&lt;P&gt;&lt;A title=LINQRayTracer.cs href="http://www.box.net/shared/3j1hts7497" mce_href="http://www.box.net/shared/3j1hts7497"&gt;&lt;IMG height=24 alt="File icon" src="http://www.box.net/thumbs/24x24/default_file.gif" width=24 align=absMiddle border=0 mce_src="http://www.box.net/thumbs/24x24/default_file.gif"&gt;LINQRayTracer.cs&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.dotnetkicks.com/kick/?url=http://blogs.msdn.com/lukeh/archive/2007/10/01/taking-linq-to-objects-to-extremes-a-fully-linqified-raytracer.aspx"&gt;&lt;IMG alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://blogs.msdn.com/lukeh/archive/2007/10/01/taking-linq-to-objects-to-extremes-a-fully-linqified-raytracer.aspx" border=0&gt;&lt;/A&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5233776" width="1" height="1"&gt;</content><author><name>LukeH</name><uri>http://blogs.msdn.com/members/LukeH.aspx</uri></author></entry><entry><title>Monadic Parser Combinators using C# 3.0</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/lukeh/archive/2007/08/19/monadic-parser-combinators-using-c-3-0.aspx" /><id>http://blogs.msdn.com/lukeh/archive/2007/08/19/monadic-parser-combinators-using-c-3-0.aspx</id><published>2007-08-20T00:33:14Z</published><updated>2007-08-20T00:33:14Z</updated><content type="html">&lt;p&gt;Parser combinators are an idea that I enjoy every time I go back and look at again.&amp;nbsp; They are an approach to building parsers by composing very simple atomic parsers into bigger and bigger&amp;nbsp;units which can ultimately express real world grammars.&amp;nbsp; This idea has been particularly popular in functional languages where the parsers can naturally be thought of as functions from input strings to parse trees, and composition of parsers is just function composition.&amp;nbsp; This approach often leads to a simple syntax which makes the resulting parsers pleasantly declarative in that internal-DSL kind of way.&amp;nbsp; &lt;/p&gt; &lt;p&gt;There's been plenty of great research and implementation of parser combinators over the last 15 years.&amp;nbsp; I can't describe it all, or even list all the references here - so let me just point you to a couple of fun papers co-authored by my Microsoft colleagues &lt;a href="http://research.microsoft.com/~emeijer/Papers/Pearl.pdf"&gt;Erik Meijer&lt;/a&gt; and &lt;a href="http://research.microsoft.com/users/daan/download/papers/parsec-paper.pdf"&gt;Daan Leijen&lt;/a&gt;.&amp;nbsp; These papers also include many references out to the broader set of research papers on the topic.&lt;/p&gt; &lt;h4&gt;Building a Parser Combinator Framework in C#3.0&lt;/h4&gt; &lt;p&gt;The code below is some sample code I wrote shortly after getting ahold of one of the first C#3.0 prototype compilers a couple years ago.&amp;nbsp; It uses some of the new languages features in interestingly unusual ways, which I'll highlight as I&amp;nbsp;go along.&amp;nbsp; For reference, it is most directly influenced by the great parser combinator example given near the end of &lt;a href="http://www.scala-lang.org/docu/files/ScalaByExample.pdf"&gt;Scala by Example&lt;/a&gt;.&lt;/p&gt; &lt;h5&gt;Step 1: A Type for Representing Parsers&lt;/h5&gt; &lt;blockquote&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.Linq;
&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.Text;

&lt;span style="color: rgb(0,128,0)"&gt;// The result of a parse consists of a value and the unconsumed input.
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Result&lt;/span&gt;&amp;lt;TInput, TValue&amp;gt; {
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; TValue Value;
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; TInput Rest;
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; Result(TValue value, TInput rest) { Value = value; Rest = rest; }
}

&lt;span style="color: rgb(0,128,0)"&gt;// A Parser is a delegate which takes an input and returns a result.
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;delegate&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Result&lt;/span&gt;&amp;lt;TInput, TValue&amp;gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, TValue&amp;gt;(TInput input);
&lt;/pre&gt;&lt;/blockquote&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;p&gt;Taking a queue from the functional language implementations, our type for representing parsers will be a delegate type.&amp;nbsp; This naturally captures the idea that a parser is a function which takes in some input, and returns a value as well as the unconsumed part of the input.&lt;/p&gt;
&lt;h5&gt;Step 2: Provide Infix AND and OR Operations on Parsers&lt;/h5&gt;
&lt;blockquote&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ParserCombinatorExtensions&lt;/span&gt; {
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, TValue&amp;gt; OR&amp;lt;TInput, TValue&amp;gt;(&lt;br&gt;        &lt;span style="color: rgb(0,0,255)"&gt;this&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, TValue&amp;gt; parser1, &lt;br&gt;        &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, TValue&amp;gt; parser2) &lt;br&gt;    {
        &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; input =&amp;gt; parser1(input) ?? parser2(input);
    }
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, TValue2&amp;gt; AND&amp;lt;TInput, TValue1, TValue2&amp;gt;(&lt;br&gt;        &lt;span style="color: rgb(0,0,255)"&gt;this&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, TValue1&amp;gt; parser1, &lt;br&gt;        &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, TValue2&amp;gt; parser2) &lt;br&gt;    {
        &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; input =&amp;gt; parser2(parser1(input).Rest);
    }
}&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;Before building any actual parsers, we'll just come up with ways to combine them.&amp;nbsp; There are two obvious ways.&amp;nbsp; Try the first one, and if it fails, apply the second one.&amp;nbsp; This corresponds to alternate productions&amp;nbsp;in a BNF grammar.&amp;nbsp; Or&amp;nbsp;we could apply the first one, and then apply the second one to whatever input is left.&amp;nbsp; This corresponds to sequencing (juxtaposition) in BNF grammars.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Note that these are extension methods applied to the Parser type, which is a delegate.&amp;nbsp; This is something we couldn't have&amp;nbsp;done in C# prior to C#&amp;nbsp;3.0, because there was no way to add methods to a delegate type.&amp;nbsp; The "infix" syntax we get by making these extension methods instead of plain static methods is very important for the readability of the resulting parsers, where ordering is critical, as the example at the end of this post will show.&lt;/p&gt;
&lt;h5&gt;Step 3: Support Composing Parsers using C# Query Expressions&lt;/h5&gt;
&lt;blockquote&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;ParserCombinatorsMonad&lt;/span&gt; {
    &lt;span style="color: rgb(0,128,0)"&gt;// By providing Select, Where and SelectMany methods on Parser&amp;lt;TInput,TValue&amp;gt; we make the 
&lt;/span&gt;    &lt;span style="color: rgb(0,128,0)"&gt;// C# Query Expression syntax available for manipulating Parsers.  
&lt;/span&gt;    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, TValue&amp;gt; Where&amp;lt;TInput, TValue&amp;gt;(&lt;br&gt;        &lt;span style="color: rgb(0,0,255)"&gt;this&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, TValue&amp;gt; parser, &lt;br&gt;        &lt;span style="color: rgb(43,145,175)"&gt;Func&lt;/span&gt;&amp;lt;TValue, &lt;span style="color: rgb(0,0,255)"&gt;bool&lt;/span&gt;&amp;gt; pred) &lt;br&gt;    {
        &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; input =&amp;gt; { 
                   &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; res = parser(input); 
                   &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (res == &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt; || !pred(res.Value)) &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;;
                   &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; res;
               };
    }
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, TValue2&amp;gt; Select&amp;lt;TInput, TValue, TValue2&amp;gt;(&lt;br&gt;        &lt;span style="color: rgb(0,0,255)"&gt;this&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, TValue&amp;gt; parser, &lt;br&gt;        &lt;span style="color: rgb(43,145,175)"&gt;Func&lt;/span&gt;&amp;lt;TValue, TValue2&amp;gt; selector) &lt;br&gt;    {
        &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; input =&amp;gt; { 
                   &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; res = parser(input);
                   &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (res == &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;) &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;;
                   &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Result&lt;/span&gt;&amp;lt;TInput, TValue2&amp;gt;(selector(res.Value), res.Rest);
               }; 
    }
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, TValue2&amp;gt; SelectMany&amp;lt;TInput, TValue, TIntermediate, TValue2&amp;gt;(&lt;br&gt;        &lt;span style="color: rgb(0,0,255)"&gt;this&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, TValue&amp;gt; parser, &lt;br&gt;        &lt;span style="color: rgb(43,145,175)"&gt;Func&lt;/span&gt;&amp;lt;TValue, &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, TIntermediate&amp;gt;&amp;gt; selector, &lt;br&gt;        &lt;span style="color: rgb(43,145,175)"&gt;Func&lt;/span&gt;&amp;lt;TValue, TIntermediate, TValue2&amp;gt; projector)
    {
        &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; input =&amp;gt; {
                   &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; res = parser(input);
                   &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (res == &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;) &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;;
                   &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; val = res.Value;
                   &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; res2 = selector(val)(res.Rest);
                   &lt;span style="color: rgb(0,0,255)"&gt;if&lt;/span&gt; (res2 == &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;) &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;;
                   &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Result&lt;/span&gt;&amp;lt;TInput, TValue2&amp;gt;(projector(val, res2.Value), res2.Rest);
               };
    }
}&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;This is where the fun really starts!&amp;nbsp; Any type which implements &lt;em&gt;Select&lt;/em&gt;, &lt;em&gt;SelectMany&lt;/em&gt; and &lt;em&gt;Where&lt;/em&gt; methods supports (part of) the "query pattern" which means we can write C#3.0 queries including multiple froms, an optional where clause and a select clause to process objects of this type.&amp;nbsp; This can make it a *lot* easier to combine parsers, and makes the syntax more transparent.&amp;nbsp; That the parsers we are using here support these three operations is captured in the idea that this parser type is a &lt;a href="http://en.wikipedia.org/wiki/Monads_in_functional_programming"&gt;monad&lt;/a&gt; - something very much in LINQ's blood - which I hope to write more about in a future post.&lt;/p&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;h5&gt;Step 4: The Fundamental Parser Combinator Building Blocks&lt;/h5&gt;
&lt;blockquote&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0,128,0)"&gt;// Contains all the basic parsers that are independent of return type.
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;abstract&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parsers&lt;/span&gt;&amp;lt;TInput&amp;gt; {
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, TValue&amp;gt; Succeed&amp;lt;TValue&amp;gt;(TValue value) {
        &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; input =&amp;gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Result&lt;/span&gt;&amp;lt;TInput, TValue&amp;gt;(value, input);
    }
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, TValue[]&amp;gt; Rep&amp;lt;TValue&amp;gt;(&lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, TValue&amp;gt; parser) {
        &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; Rep1(parser).OR(Succeed(&lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; TValue[0]));
    }
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, TValue[]&amp;gt; Rep1&amp;lt;TValue&amp;gt;(&lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, TValue&amp;gt; parser) {
        &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; x &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; parser 
               &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; xs &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; Rep(parser)
               &lt;span style="color: rgb(0,0,255)"&gt;select&lt;/span&gt; (&lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt;[] { x }).Concat(xs).ToArray();
    }
}

&lt;span style="color: rgb(0,128,0)"&gt;// Contains a few parsers that parse characters from an input stream
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;abstract&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;CharParsers&lt;/span&gt;&amp;lt;TInput&amp;gt; : &lt;span style="color: rgb(43,145,175)"&gt;Parsers&lt;/span&gt;&amp;lt;TInput&amp;gt; {
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;abstract&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, &lt;span style="color: rgb(0,0,255)"&gt;char&lt;/span&gt;&amp;gt; AnyChar { &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt;; }
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, &lt;span style="color: rgb(0,0,255)"&gt;char&lt;/span&gt;&amp;gt; Char(&lt;span style="color: rgb(0,0,255)"&gt;char&lt;/span&gt; ch) { &lt;br&gt;        &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; c &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; AnyChar &lt;span style="color: rgb(0,0,255)"&gt;where&lt;/span&gt; c == ch &lt;span style="color: rgb(0,0,255)"&gt;select&lt;/span&gt; c; &lt;br&gt;    }
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, &lt;span style="color: rgb(0,0,255)"&gt;char&lt;/span&gt;&amp;gt; Char(&lt;span style="color: rgb(43,145,175)"&gt;Predicate&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;char&lt;/span&gt;&amp;gt; pred) { &lt;br&gt;        &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; c &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; AnyChar &lt;span style="color: rgb(0,0,255)"&gt;where&lt;/span&gt; pred(c) &lt;span style="color: rgb(0,0,255)"&gt;select&lt;/span&gt; c; &lt;br&gt;    }
}&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;So now we need to write some (almost) real parsers.&amp;nbsp; The &lt;em&gt;Succeed&lt;/em&gt; parser always succeeds with the provided result without consuming any input.&amp;nbsp; Rep and Rep1 apply a parser repeatedly, they differ only in whether they require the parser to parse at least once.&amp;nbsp; Note that Rep1 uses Query Expressions to capture&amp;nbsp;the&amp;nbsp;idea of parsing using "parser", then parsing using "Rep(parser)" then returning a result&amp;nbsp;built out of the two individual results.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;The AnyChar and Char parsers parse actual characters out of the input stream.&amp;nbsp; AnyChar parses any single character, whereas the two overloads of Char only accept certain classes of characters.&amp;nbsp; Note that AnyChar is defined abstract because it can only be implemented once we've decided what kind of input we're going to parse - but we want to be able to build on it without committing to a particular input type.&lt;/p&gt;
&lt;h5&gt;Step 5: An Example Parser for a MiniML Language &lt;/h5&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;
&lt;blockquote&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0,128,0)"&gt;// Term and its derived classes define the AST for terms in the MiniML language.
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;abstract&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt; { }
&lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;LambdaTerm&lt;/span&gt; : &lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt; { &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt; Ident; &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt; Term; &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; LambdaTerm(&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt; i, &lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt; t) { Ident = i; Term = t; } }
&lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;LetTerm&lt;/span&gt; : &lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt; { &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt; Ident; &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt; Rhs; &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt; Body; &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; LetTerm(&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt; i, &lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt; r, &lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt; b) { Ident = i; Rhs = r; Body = b; } }
&lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;AppTerm&lt;/span&gt; : &lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt; { &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt; Func; &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt;[] Args; &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; AppTerm(&lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt; func, &lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt;[] args) { Func = func; Args = args; } }
&lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;VarTerm&lt;/span&gt; : &lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt; { &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;readonly&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt; Ident; &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; VarTerm(&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt; ident) { Ident = ident; } }

&lt;span style="color: rgb(0,128,0)"&gt;// Provides a set of parsers for the MiniML Language defined above.  
&lt;/span&gt;&lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;abstract&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;MiniMLParsers&lt;/span&gt;&amp;lt;TInput&amp;gt; : &lt;span style="color: rgb(43,145,175)"&gt;CharParsers&lt;/span&gt;&amp;lt;TInput&amp;gt;{
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; MiniMLParsers() {
        Whitespace = Rep(Char(&lt;span style="color: rgb(163,21,21)"&gt;' '&lt;/span&gt;).OR(Char(&lt;span style="color: rgb(163,21,21)"&gt;'\t'&lt;/span&gt;).OR(Char(&lt;span style="color: rgb(163,21,21)"&gt;'\n'&lt;/span&gt;)).OR(Char(&lt;span style="color: rgb(163,21,21)"&gt;'\r'&lt;/span&gt;))));
        WsChr =  chr =&amp;gt; Whitespace.AND(Char(chr));
        Id =     &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; w &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; Whitespace
                 &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; c &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; Char(&lt;span style="color: rgb(0,0,255)"&gt;char&lt;/span&gt;.IsLetter)
                 &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; cs &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; Rep(Char(&lt;span style="color: rgb(0,0,255)"&gt;char&lt;/span&gt;.IsLetterOrDigit))
                 &lt;span style="color: rgb(0,0,255)"&gt;select&lt;/span&gt; cs.Aggregate(c.ToString(),(acc,ch) =&amp;gt; acc+ch);
        Ident =  &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; s &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; Id &lt;span style="color: rgb(0,0,255)"&gt;where&lt;/span&gt; s != &lt;span style="color: rgb(163,21,21)"&gt;"let"&lt;/span&gt; &amp;amp;&amp;amp; s != &lt;span style="color: rgb(163,21,21)"&gt;"in"&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;select&lt;/span&gt; s;
        LetId =  &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; s &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; Id &lt;span style="color: rgb(0,0,255)"&gt;where&lt;/span&gt; s == &lt;span style="color: rgb(163,21,21)"&gt;"let"&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;select&lt;/span&gt; s;
        InId =   &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; s &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; Id &lt;span style="color: rgb(0,0,255)"&gt;where&lt;/span&gt; s == &lt;span style="color: rgb(163,21,21)"&gt;"in"&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;select&lt;/span&gt; s;
        Term1 = (&lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; x &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; Ident 
                 &lt;span style="color: rgb(0,0,255)"&gt;select&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt;)&lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;VarTerm&lt;/span&gt;(x))
                .OR(
                (&lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; u1 &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; WsChr(&lt;span style="color: rgb(163,21,21)"&gt;'('&lt;/span&gt;) 
                 &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; t &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; Term 
                 &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; u2 &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; WsChr(&lt;span style="color: rgb(163,21,21)"&gt;')'&lt;/span&gt;) 
                 &lt;span style="color: rgb(0,0,255)"&gt;select&lt;/span&gt; t));
        Term =  (&lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; u1 &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; WsChr(&lt;span style="color: rgb(163,21,21)"&gt;'\\'&lt;/span&gt;)
                 &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; x &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; Ident
                 &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; u2 &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; WsChr(&lt;span style="color: rgb(163,21,21)"&gt;'.'&lt;/span&gt;)
                 &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; t &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; Term
                 &lt;span style="color: rgb(0,0,255)"&gt;select&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt;)&lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;LambdaTerm&lt;/span&gt;(x,t))
                .OR(
                (&lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; letid &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; LetId
                 &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; x &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; Ident
                 &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; u1 &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; WsChr(&lt;span style="color: rgb(163,21,21)"&gt;'='&lt;/span&gt;)
                 &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; t &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; Term
                 &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; inid &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; InId
                 &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; c &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; Term
                 &lt;span style="color: rgb(0,0,255)"&gt;select&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt;)&lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;LetTerm&lt;/span&gt;(x,t,c)))
                .OR(
                (&lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; t &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; Term1
                 &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; ts &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; Rep(Term1)
                 &lt;span style="color: rgb(0,0,255)"&gt;select&lt;/span&gt; (&lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt;)&lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;AppTerm&lt;/span&gt;(t,ts)));
        All =    &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; t &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; Term &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; u &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; WsChr(&lt;span style="color: rgb(163,21,21)"&gt;';'&lt;/span&gt;) &lt;span style="color: rgb(0,0,255)"&gt;select&lt;/span&gt; t;
    }
   
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, &lt;span style="color: rgb(0,0,255)"&gt;char&lt;/span&gt;[]&amp;gt; Whitespace;
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;char&lt;/span&gt;, &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, &lt;span style="color: rgb(0,0,255)"&gt;char&lt;/span&gt;&amp;gt;&amp;gt; WsChr;
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, &lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;&amp;gt; Id;
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, &lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;&amp;gt; Ident;
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, &lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;&amp;gt; LetId;
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, &lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;&amp;gt; InId;
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, &lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt;&amp;gt; Term;
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, &lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt;&amp;gt; Term1;
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;TInput, &lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt;&amp;gt; All;
}&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Here we've used the parsers built&amp;nbsp;so far to implemented a parser for a (toy) language called MiniML.&amp;nbsp; You can immediately see that the parser is structured much like the BNF it implements - which is the internal-DSL concept I mentioned above.&amp;nbsp; You can also see how C# Query Expressions are used to help with this -&amp;nbsp;in a context that is very different than their standard query usage.&lt;/p&gt;
&lt;h5&gt;Step 6: Parse Something!&lt;/h5&gt;
&lt;blockquote&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;MiniMLParserFromString&lt;/span&gt;: &lt;span style="color: rgb(43,145,175)"&gt;MiniMLParsers&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;&amp;gt; {
    &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;override&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Parser&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;, &lt;span style="color: rgb(0,0,255)"&gt;char&lt;/span&gt;&amp;gt; AnyChar {
        &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt; { { &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; input =&amp;gt; input.Length &amp;gt; 0 ? &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Result&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;,&lt;span style="color: rgb(0,0,255)"&gt;char&lt;/span&gt;&amp;gt;(input[0], input.Substring(1)) : &lt;span style="color: rgb(0,0,255)"&gt;null&lt;/span&gt;; } }
    }   
}&lt;/pre&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Program &lt;/span&gt;{
    &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; Main(&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;[] args) {
        &lt;span style="color: rgb(43,145,175)"&gt;MiniMLParserFromString&lt;/span&gt; parser = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;MiniMLParserFromString&lt;/span&gt;();
        &lt;span style="color: rgb(43,145,175)"&gt;Result&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;,&lt;span style="color: rgb(43,145,175)"&gt;Term&lt;/span&gt;&amp;gt; result = 
            parser.All(&lt;span style="color: rgb(163,21,21)"&gt;@"let true = \x.\y.x in 
                         let false = \x.\y.y in 
                         let if = \b.\l.\r.(b l) r in
                         if true then false else true;"&lt;/span&gt;);
    }
}&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;We finally have something we can execute!&amp;nbsp; &lt;em&gt;MiniMLParserFromString &lt;/em&gt;makes everything concrete by describing how to parse characters from a string input.&amp;nbsp; And then in the Main method we see an example which parsers a little example expression from the MiniML language.&lt;/p&gt;
&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;The little parser combinator framework here is very much a toy implementation.&amp;nbsp; It's horribly inefficient, doesn't do error reporting, and doesn't support any form of error recovery.&amp;nbsp; But it's a fun 150 lines of code!&amp;nbsp; If you are interested in the more practical applications of parser combinators - these papers provide a lot of good ideas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;"&lt;a href="http://citeseer.ist.psu.edu/rd/3944012%2C227614%2C1%2C0.25%2CDownload/http://citeseer.ist.psu.edu/cache/papers/cs/9234/ftp:zSzzSzftp.cs.kun.nlzSzpubzSzCSIzSzSoftwEng.FunctLangzSzpaperszSzkoop98-EffCombParsIFL98.pdf/koopman98efficient.pdf"&gt;Efficient Parser Combinators&lt;/a&gt;", Pieter Koopman and Rinus Plasmeijer, 1998 
&lt;li&gt;"&lt;a href="http://people.cs.uu.nl/doaitse/Papers/1999/SofSem99.pdf"&gt;Fast, Error Correcting Parser Combinators: A Short Tutorial&lt;/a&gt;",&amp;nbsp;S. Doaitse Swierstra and Pablo R. Azero Alcocer, 1999 
&lt;li&gt;"&lt;a href="http://legacy.cs.uu.nl/daan/download/papers/parsec-paper.pdf"&gt;Parsec: Direct Style Monadic Parser Combinators for the Real World&lt;/a&gt;", Daan Leijen and Erik Meijer, 2001.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;And here's the code:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.box.net/shared/nk3nqefj80"&gt;&lt;img height="24" alt="File icon" src="http://www.box.net/thumbs/24x24/default_file.gif" width="24" align="absMiddle" border="0"&gt;ParserCombinators.cs&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4469181" width="1" height="1"&gt;</content><author><name>LukeH</name><uri>http://blogs.msdn.com/members/LukeH.aspx</uri></author></entry><entry><title>C# 3.0 and CodeDOM</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/lukeh/archive/2007/07/11/c-3-0-and-codedom.aspx" /><id>http://blogs.msdn.com/lukeh/archive/2007/07/11/c-3-0-and-codedom.aspx</id><published>2007-07-11T23:13:19Z</published><updated>2007-07-11T23:13:19Z</updated><content type="html">&lt;p&gt;The CodeDOM is a very handy .NET API which allows you to programatically compile code using the .NET compilers and programatically construct code without just pasting together strings.&amp;nbsp; &lt;/p&gt; &lt;p&gt;With the new version of the language, we've heard a numer of questions about how to use the CodeDOM with the new compiler.&lt;/p&gt; &lt;p&gt;There are two aspects to the inegration of C#3.0 with CodeDOM:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Programatically &lt;strong&gt;compiling &lt;/strong&gt;C# source code: This is supported in .NET3.5.&amp;nbsp; The existing CodeDOM is augmented with an overload of CSharpCodeProvider which takes a "providerOptions" argument.&amp;nbsp; This can be used to point CodeDOM at the new .NET Framework 3.5 C# compiler (which supports C#3.0), by passing a "providerOptions" dictionary containing "CompilerVersion" as "v3.5".&amp;nbsp; This can also be controlled via the .config file, which is done&amp;nbsp; for example in Orcas ASP.NET websites targeting .NET3.5.&amp;nbsp; &lt;br&gt;&lt;br&gt; &lt;li&gt;Programatically &lt;strong&gt;constructing &lt;/strong&gt;C#3.0 source code:&amp;nbsp; There won't be support for the this in the .NET Framework 3.5 CodeDOM that ships with Orcas.&amp;nbsp; Luckily, very few of the C# 3.0 features need CodeDOM support - since most new features are expressions, and the CodeDOM doesn't go down to the&amp;nbsp;expression level.&amp;nbsp; &lt;/li&gt;&lt;/ul&gt; &lt;h6&gt;Example of programatically compiling C#3.0 source code:&lt;/h6&gt; &lt;p&gt;&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System;&lt;br&gt;&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br&gt;&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.Linq;&lt;br&gt;&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; Microsoft.CSharp;&lt;br&gt;&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.CodeDom.Compiler;&lt;br&gt;&lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Program&lt;br&gt;&lt;/span&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; Main(&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;[] args)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; csc = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;CSharpCodeProvider&lt;/span&gt;(&lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;, &lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;&amp;gt;() { { &lt;span style="color: rgb(163,21,21)"&gt;"CompilerVersion"&lt;/span&gt;, &lt;span style="color: rgb(163,21,21)"&gt;"v3.5"&lt;/span&gt; } });&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; parameters = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;CompilerParameters&lt;/span&gt;(&lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt;[] { &lt;span style="color: rgb(163,21,21)"&gt;"mscorlib.dll"&lt;/span&gt;, &lt;span style="color: rgb(163,21,21)"&gt;"System.Core.dll"&lt;/span&gt; }, &lt;span style="color: rgb(163,21,21)"&gt;"foo.exe"&lt;/span&gt;, &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; parameters.GenerateExecutable = &lt;span style="color: rgb(0,0,255)"&gt;true&lt;/span&gt;;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(43,145,175)"&gt;CompilerResults&lt;/span&gt; results = csc.CompileAssemblyFromSource(parameters,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(163,21,21)"&gt;@"using System.Linq;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; class Program {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void Main(string[] args) {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var q = from i in Enumerable.Rnge(1,100)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; where i % 2 == 0&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select i;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }"&lt;/span&gt;);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; results.Errors.Cast&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;CompilerError&lt;/span&gt;&amp;gt;().ToList().ForEach(error =&amp;gt; &lt;span style="color: rgb(43,145,175)"&gt;Console&lt;/span&gt;.WriteLine(error.ErrorText));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3819120" width="1" height="1"&gt;</content><author><name>LukeH</name><uri>http://blogs.msdn.com/members/LukeH.aspx</uri></author></entry><entry><title>.NET Framework Multitargeting in Visual Studio 2008 (aka Orcas)</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/lukeh/archive/2007/06/29/net-framework-multitargeting-in-visual-studio-2008-aka-orcas.aspx" /><id>http://blogs.msdn.com/lukeh/archive/2007/06/29/net-framework-multitargeting-in-visual-studio-2008-aka-orcas.aspx</id><published>2007-06-30T01:54:00Z</published><updated>2007-06-30T01:54:00Z</updated><content type="html">&lt;P mce_keep="true"&gt;One of the really great features I worked on for our upcoming release is ".NET Framework Multitargeting" for Visual Studio.&amp;nbsp; This allows you to build applications targeting any of these frameworks using Visual Studio 2008:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;.NET Framework 2.0&lt;/STRONG&gt; - released with Visual Studio 2005 
&lt;LI&gt;&lt;STRONG&gt;.NET Framework 3.0&lt;/STRONG&gt; - released&amp;nbsp;with Windows Vista 
&lt;LI&gt;&lt;STRONG&gt;.NET Framework 3.5&lt;/STRONG&gt; - will release with Visual Studio Orcas&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;When targeting .NET Framework 2.0, for example, Visual Studio will try to protect you from using any features that are only available in a higher framework version.&amp;nbsp; This lets you confidently use Visual Studio 2008 for targeting any of these three platforms.&amp;nbsp; New projects can be created targeting any of these frameworks, and projects can later be changed to target a different framework.&lt;/P&gt;
&lt;H4&gt;Why is this so important?&lt;/H4&gt;
&lt;P&gt;We've heard over-and-over again from .NET developers about how much harder it is to move to the next framework version than to&amp;nbsp;move to the next Visual Studio version.&amp;nbsp; Upgrading to a new Visual Studio means installing on a few developer machines - upgrading to target a new framework means ensuring that every client of the application has the new framework installed.&amp;nbsp; Because of this, we very often get asked about whether it's possible to target the older frameworks with the newer tools.&amp;nbsp; With Visual Studio 2008 - we're enabling just that.&lt;/P&gt;
&lt;P&gt;There's another reason this is important for Visual Studio 2008 in particular.&amp;nbsp; With .NET 2.0, .NET 3.0 and .NET 3.5, we'll have released three framework versions in about 2 years - but only two Visual Studio versions.&amp;nbsp; Because of this - Visual Studio 2008 needs to be a great tool for targeting both .NET3.0 and .NET3.5, and multitrargeting enables this.&amp;nbsp; In addition, we want developers and development organizations to be able to easily move from Visual Studio 2005 to Visual Studio 2008 - and support for multitargeting lowers the barrier to entry - you can continue working on your .NET 2.0 applications in Visual Studio 2008.&lt;/P&gt;
&lt;H4&gt;A few details...&lt;/H4&gt;
&lt;H5&gt;New Project Dialog&lt;/H5&gt;
&lt;P&gt;The New Project and New Website dialogs now have an additional UI element to choose the framework version to target.&amp;nbsp; Choosing a target will limit the set of available templates in the dialog.&amp;nbsp; Additionally, templates that are available for multiple targets will be generated with different default references and usings/imports based on the framework target.&amp;nbsp; Out of the box, the defaults are to target .NET3.5 - but, just like other options in the dialog, the choice is "sticky", so if you pick .NET2.0, it'll default to that in the future.&lt;/P&gt;
&lt;P&gt;Since some templates are unaffected by the .NET Framework target - the description of the template also mentions whether or not a specific .NET Framework target will be applied.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20New%20Project%20Dialog%20-%20small%5B2%5D.png" mce_href="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20New%20Project%20Dialog%20-%20small%5B2%5D.png" atomicselection="true"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=405 src="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20New%20Project%20Dialog%20-%20small_thumb.png" width=603 border=0 mce_src="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20New%20Project%20Dialog%20-%20small_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;H5&gt;Project Properties&lt;/H5&gt;
&lt;P&gt;You can change the framework target of your project at any time through the Project-&amp;gt;Properties dialog.&amp;nbsp; If you change the target to a higher framework version, you&amp;nbsp;will be able to&amp;nbsp;use the new API features available in that framework.&amp;nbsp; If you change the target to a lower framework version,&amp;nbsp;any references in your project which are no longer allowed will be disabled (but left in your References list), and compiling your project will likely result in build failures&amp;nbsp;due to the missing assemblies.&amp;nbsp;&amp;nbsp;However, we've&amp;nbsp;tried to ensure that&amp;nbsp;changing to a lower framework is&amp;nbsp;easily reversible.&lt;/P&gt;
&lt;P&gt;In C# projects, the drop-down to make these changes appears on the Application tab, for VB projects it appears in the Compiler-&amp;gt;Advanced... tab and for C++ projects it appears in the Framework and References section.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Project%20Properties%20-%20small%5B2%5D.png" mce_href="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Project%20Properties%20-%20small%5B2%5D.png" atomicselection="true"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=424 src="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Project%20Properties%20-%20small_thumb.png" width=606 border=0 mce_src="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Project%20Properties%20-%20small_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;H5&gt;Add Reference Dialog&lt;/H5&gt;
&lt;P&gt;The real heart of multitargeting support is the Add Reference dialog (see "So, how does this work?" below for details).&lt;/P&gt;
&lt;P&gt;In the ".NET" tab, references which are not available for the target framework are grayed out and cannot be added.&amp;nbsp; A hover-tip message explains the reason why.&amp;nbsp; All the assemblies that ship as part of the higher frameworks will be grayed out, as will any other assemblies which themselves have references to assemblies in the higher frameworks.&lt;/P&gt;
&lt;P&gt;In the "Browse" tab, you can still browse to any assembly, but if that assembly requires a higher framework version than your project, a warning dialog will be presented.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Add%20Reference%20Dialog%20-small%5B2%5D.png" mce_href="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Add%20Reference%20Dialog%20-small%5B2%5D.png" atomicselection="true"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=305 src="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Add%20Reference%20Dialog%20-small_thumb.png" width=362 border=0 mce_src="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Add%20Reference%20Dialog%20-small_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;H5&gt;Add New Item Dialog&lt;/H5&gt;
&lt;P&gt;Some of the items that can be added to a project are dependent on a minimum framework version.&amp;nbsp; For example the "Linq to SQL Classes" item template requires .NET 3.5.&amp;nbsp; The Add New Item dialog thus filters out these items that are not available for the project.&amp;nbsp; Custom or third party templates can also set the framework versions they want to be available in - so that they can integrate correctly into this filtering.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Add%20New%20Item%20Dialog%20-%20small%5B4%5D.png" mce_href="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Add%20New%20Item%20Dialog%20-%20small%5B4%5D.png" atomicselection="true"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=362 src="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Add%20New%20Item%20Dialog%20-%20small_thumb.png" width=603 border=0 mce_src="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Add%20New%20Item%20Dialog%20-%20small_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;H5&gt;Toolbox&lt;/H5&gt;
&lt;P&gt;The toolbox provides controls from many different assemblies - some of which may not be available for the framework target of your project.&amp;nbsp; So any controls defined in assemblies which are not available on your target framework will be filtered out of the toolbox.&amp;nbsp; For example, the ElementHost WinForms control which allows WPF interop as part of .NET3.0 is not available in the toolbox when building a WinForms project targeting .NET 2.0.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Toolbox%20-%20small%5B2%5D.png" mce_href="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Toolbox%20-%20small%5B2%5D.png" atomicselection="true"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=411 src="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Toolbox%20-%20small_thumb.png" width=571 border=0 mce_src="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Toolbox%20-%20small_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;H5&gt;Deployment&lt;/H5&gt;
&lt;P&gt;At the end of the day, .NET framework target is all about deployment prequisites.&amp;nbsp; So in the Prerequisites dialog we've provided a few options for which .NET Framework package to include with your deployment.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Deployment%20Prerequisites%20Dialog%20-%20small%5B2%5D.png" mce_href="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Deployment%20Prerequisites%20Dialog%20-%20small%5B2%5D.png" atomicselection="true"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=346 src="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Deployment%20Prerequisites%20Dialog%20-%20small_thumb.png" width=448 border=0 mce_src="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Deployment%20Prerequisites%20Dialog%20-%20small_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;H5&gt;Language&lt;/H5&gt;
&lt;P&gt;Many of the new language features in the&amp;nbsp;.NET languages can be used with any of the available .NET framework targets.&amp;nbsp; So Visual Studio 2008 allows you to use C#3.0, VB9, and VC9 for all projects, including those targeting .NET2.0 and .NET3.0.&lt;/P&gt;
&lt;P&gt;Websites are different in this regard - you cannot use the new language features in a web site targeting .NET 2.0 or .NET 3.0.&amp;nbsp; This restriction is in place because Web Sites need to compile on the web server, and this requires that the new compilers be installed on the Web Server.&amp;nbsp; Since these new compilers come as part of the .NET 3.5 framework, this framework is required on the web server to use new language features.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20CSharp%20Editor%20-%20small%5B2%5D.png" mce_href="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20CSharp%20Editor%20-%20small%5B2%5D.png" atomicselection="true"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=409 src="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20CSharp%20Editor%20-%20small_thumb.png" width=514 border=0 mce_src="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20CSharp%20Editor%20-%20small_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;H5&gt;Express&lt;/H5&gt;
&lt;P&gt;The Visual Studio 2008 Express products have a limited version of multitargeting.&amp;nbsp; All of the infrastructure described above is available - except for the dropdown in the New Project Dialog.&amp;nbsp; This keeps the multitargeting features out of the way for beginning and hobbyist developers - but ensures that projects can continue to move between Express and full versions of Visual Studio as they could in Visual Studio 2005. &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;A href="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Express%20-%20small%5B2%5D.png" mce_href="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Express%20-%20small%5B2%5D.png" atomicselection="true"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=360 src="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Express%20-%20small_thumb.png" width=603 border=0 mce_src="http://blogs.msdn.com/blogfiles/lukeh/WindowsLiveWriter/f4e.NETFrameworkMultitargetinginVisualSt_DF9D/Multitargeting%20-%20Express%20-%20small_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;H4&gt;So, how does this work?&lt;/H4&gt;
&lt;P&gt;The three frameworks supported by Visual Studio Orcas are each supersets of one another - instead of being replacements as the previous .NET Framework releases have been.&amp;nbsp; One benefit of this is that .NET Framework Multitargeting can be based just on the available set of references.&amp;nbsp; That is - when you target .NET3.0, the only things you should be prevented from using are those that depend on assemblies in .NET3.5 - and this can be done by ensuring that you don't accidentally reference these assemblies.&lt;/P&gt;
&lt;P&gt;There is one caveat to this - called "red bits".&amp;nbsp; These are the changes in the framework that are part of .NET Framework 2.0 Service Pack 1 and .NET Framework 3.0 Service Pack 1, both of which will be released along with Visual Studio 2008.&amp;nbsp; These two service packs are required for .NET3.5 to be installed, and they include a few very targetted additions of new functionality to the .NET 2.0 and .NET 3.0 frameworks.&amp;nbsp; This means that when you target .NET 2.0 in Visual Studio Orcas, you are really targeting .NET 2.0 SP1.&amp;nbsp; This is similar to what happens when you are using Visual Studio 2003 after the .NET Framework 1.1 service pack is installed on your machine - so it's really nothing new.&amp;nbsp; But for those who want to be extra cautious about their framework dependencies, it's somthing to be aware of.&amp;nbsp;&lt;/P&gt;
&lt;H4&gt;Try it Now!&lt;/H4&gt;
&lt;P&gt;Orcas Beta1 is available &lt;A href="http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx" mce_href="http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx"&gt;now&lt;/A&gt;, and includes almost all of the multitargeting support described above.&amp;nbsp; Take a look and let us know what you think.&amp;nbsp; Orcas Beta2, which will be available later&amp;nbsp;this summer, will include everything described here - along with a ton of other improvements and bug fixes across the rest of&amp;nbsp;Visual Studio 2008 and the .NET 3.5 Framework.&amp;nbsp; As always, send us feedback through &lt;A href="http://connect.microsoft.com/feedback/default.aspx?SiteID=210" mce_href="http://connect.microsoft.com/feedback/default.aspx?SiteID=210"&gt;Connect&lt;/A&gt;.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3611363" width="1" height="1"&gt;</content><author><name>LukeH</name><uri>http://blogs.msdn.com/members/LukeH.aspx</uri></author></entry><entry><title>C#3.0 Session at TechEd2007 - Code Samples</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/lukeh/archive/2007/06/07/c-3-0-session-at-teched2007-code-samples.aspx" /><id>http://blogs.msdn.com/lukeh/archive/2007/06/07/c-3-0-session-at-teched2007-code-samples.aspx</id><published>2007-06-07T17:42:27Z</published><updated>2007-06-07T17:42:27Z</updated><content type="html">&lt;p&gt;I just presented my C#3.0 session at TechEd Orlando titled "DEV346 - Microsoft Visual C# Under the Covers: An In-Depth Look at C# 3.0".&amp;nbsp; The talk introduces the new C# language features and takes a tour behind the scenes of LINQ to Objects to see how C# is used to enable creating rich new kinds of APIs.&lt;/p&gt; &lt;p&gt;Here are the code samples from the talk:&lt;/p&gt; &lt;p&gt;&lt;a title="FirstDemo.cs" href="http://www.box.net/shared/mknrbvkbxa"&gt;&lt;img height="24" alt="File icon" src="http://www.box.net/thumbs/24x24/default_file.gif" width="24" align="absMiddle" border="0"&gt;FirstDemo.cs&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a title="SecondDemo.cs" href="http://www.box.net/shared/je4tdqvl3c"&gt;&lt;img height="24" alt="File icon" src="http://www.box.net/thumbs/24x24/default_file.gif" width="24" align="absMiddle" border="0"&gt;SecondDemo.cs&lt;/a&gt;&lt;/p&gt; &lt;p&gt;And here's a little in-line snippet - the results of the first demo:&lt;/p&gt; &lt;p&gt;&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System;&lt;br&gt;&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br&gt;&lt;span style="color: rgb(0,0,255)"&gt;using&lt;/span&gt; System.Linq;&lt;br&gt;&lt;br&gt;&lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Customer&lt;br&gt;&lt;/span&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,128,0)"&gt;// C#3.0 Feature:&amp;nbsp; Auto-Implemented Properties&lt;br&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt; CustomerID { &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt;; &lt;span style="color: rgb(0,0,255)"&gt;set&lt;/span&gt;; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt; ContactName { &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt;; &lt;span style="color: rgb(0,0,255)"&gt;set&lt;/span&gt;; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt; City { &lt;span style="color: rgb(0,0,255)"&gt;get&lt;/span&gt;; &lt;span style="color: rgb(0,0,255)"&gt;set&lt;/span&gt;; }&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Program&lt;br&gt;&lt;/span&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; Main(&lt;span style="color: rgb(0,0,255)"&gt;string&lt;/span&gt;[] args)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(43,145,175)"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;Customer&lt;/span&gt;&amp;gt; customers = LoadCustomers();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: rgb(0,128,0)"&gt;// C#3.0 Feature:&amp;nbsp; Query Expressions&lt;br&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; query = &lt;span style="color: rgb(0,0,255)"&gt;from&lt;/span&gt; c &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; customers&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,0,255)"&gt;where&lt;/span&gt; c.City == &lt;span style="color: rgb(163,21,21)"&gt;"London"&lt;br&gt;&lt;/span&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; &lt;span style="color: rgb(0,0,255)"&gt;orderby&lt;/span&gt; c.ContactName.Split(&lt;span style="color: rgb(163,21,21)"&gt;' '&lt;/span&gt;)[1]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;span style="color: rgb(0,0,255)"&gt;select&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; { c.CustomerID, c.ContactName };&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,0,255)"&gt;foreach&lt;/span&gt; (&lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; item &lt;span style="color: rgb(0,0,255)"&gt;in&lt;/span&gt; query)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(43,145,175)"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: rgb(163,21,21)"&gt;"{0}, {1}"&lt;/span&gt;, item.CustomerID, item.ContactName);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;Customer&lt;/span&gt;&amp;gt; LoadCustomers()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,128,0)"&gt;// C#3.0 Feature:&amp;nbsp; 'var' - Local Variable Type Inference&lt;br&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,128,0)"&gt;// C#3.0 Feature:&amp;nbsp; Collection Initializers&lt;br&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,0,255)"&gt;var&lt;/span&gt; customers = &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43,145,175)"&gt;Customer&lt;/span&gt;&amp;gt;() &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,128,0)"&gt;// C#3.0 Feature:&amp;nbsp; Object Initializers&lt;br&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Customer&lt;/span&gt; { CustomerID = &lt;span style="color: rgb(163,21,21)"&gt;"ALFKI"&lt;/span&gt;, &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ContactName = &lt;span style="color: rgb(163,21,21)"&gt;"Maria Anders"&lt;/span&gt;, &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; City = &lt;span style="color: rgb(163,21,21)"&gt;"Berlin"&lt;/span&gt;},&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Customer&lt;/span&gt; { CustomerID = &lt;span style="color: rgb(163,21,21)"&gt;"ANATR"&lt;/span&gt;, &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ContactName = &lt;span style="color: rgb(163,21,21)"&gt;"Ana Trujillo"&lt;/span&gt;, &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; City = &lt;span style="color: rgb(163,21,21)"&gt;"M?xico D.F."&lt;/span&gt;},&lt;br&gt;&lt;span style="color: rgb(0,0,255)"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#808080"&gt;// m&lt;/font&gt;&lt;/span&gt;&lt;font color="#808080"&gt;ore customers ...&lt;/font&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,0,255)"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43,145,175)"&gt;Customer&lt;/span&gt; { CustomerID = &lt;span style="color: rgb(163,21,21)"&gt;"WOLZA"&lt;/span&gt;, &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ContactName = &lt;span style="color: rgb(163,21,21)"&gt;"Zbyszek Piestrzeniewicz"&lt;/span&gt;, &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; City = &lt;span style="color: rgb(163,21,21)"&gt;"Warszawa"&lt;/span&gt;}&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,0,255)"&gt;return&lt;/span&gt; customers;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;/p&gt; &lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3142682" width="1" height="1"&gt;</content><author><name>LukeH</name><uri>http://blogs.msdn.com/members/LukeH.aspx</uri></author></entry></feed>