<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://cs.hubfs.net/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>hubFS: THE place for F#</title><link>http://cs.hubfs.net/blogs/default.aspx</link><description>. . . are you on The Hub?</description><dc:language>en-US</dc:language><generator>CommunityServer 2.0 (Build: 60217.2664)</generator><item><title>Download F# in Visual Studio 2010 Beta2, or matching F# CTP Update for VS2008</title><link>http://cs.hubfs.net/blogs/f_team/archive/2009/10/19/12030.aspx</link><pubDate>Mon, 19 Oct 2009 21:37:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:12030</guid><dc:creator>dsyme</dc:creator><slash:comments>0</slash:comments><description>
F# in Visual Studio 2010 Beta2, plus matching F# CTP Update for VS2008


The latest release of F# is now out! See the post on Don Syme's blog.

...(&lt;a href="http://cs.hubfs.net/blogs/f_team/archive/2009/10/19/12030.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=12030" width="1" height="1"&gt;</description></item><item><title>hubFS: Email Notifications</title><link>http://cs.hubfs.net/blogs/thepopeofthehub/archive/2009/10/10/11980.aspx</link><pubDate>Sat, 10 Oct 2009 14:22:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:11980</guid><dc:creator>optionsScalper</dc:creator><slash:comments>1</slash:comments><description>&lt;P&gt;Spammers are a constant issue when running a public site.&amp;nbsp; I've taken normal precautions and the site seems relatively clean.&amp;nbsp; Unfortunately, some of the spammers expect reply emails to undeliverable addresses.&amp;nbsp; This has caused my hosting service some issues with email blacklisting.&lt;/P&gt;
&lt;P&gt;I've disabled email notifications until I can find a more suitable approach to this problem.&amp;nbsp; I'll be trying another provider for my SMTP services as a first attempt, but I will likely need a more general approach as to how to deal with email replies to illegitimate users.&lt;/P&gt;
&lt;P&gt;In the meantime, please email me with concerns, suggestions, etc.&amp;nbsp; I would especially like to hear from you if you feel this is critical to your usage of hubFS.&amp;nbsp; Send to:&lt;/P&gt;
&lt;P&gt;os #at# jjbresearch.org&lt;/P&gt;
&lt;P&gt;with the subject line containing "HubFS EMAIL".&lt;/P&gt;
&lt;P&gt;Thanks for your patience.&lt;/P&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=11980" width="1" height="1"&gt;</description></item><item><title>Introducing F# - Four part webcast series</title><link>http://cs.hubfs.net/blogs/tomasp/archive/2009/06/16/fsharp_webcast.aspx</link><pubDate>Tue, 16 Jun 2009 00:32:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:10966</guid><dc:creator>tomasp</dc:creator><slash:comments>1</slash:comments><description>&lt;P&gt;Now that &lt;A href="http://www.microsoft.com/visualstudio/en-us/products/2010/default.mspx"&gt;Visual Studio 2010 Beta 1&lt;/A&gt; is out, it is finally a good time to take a look at one of the (in my opinion) most interesting new features in the new release - &lt;A href="http://blogs.msdn.com/dsyme/archive/2009/05/20/visual-studio-2010-beta1-with-f-is-now-available-plus-matching-f-ctp-update-for-vs2008.aspx"&gt;the F# language&lt;/A&gt;. As all the regular hubFS readers know, F# existed for quite a long time now as Microsoft Research project, but is now becoming a real Microsoft product. Interestingly, F# is still available as a &lt;A href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=7bb32f32-9fac-4f34-ad56-b0bda130cf00"&gt;plugin for Visual Studio 2008&lt;/A&gt;, so if you want to try it you don't have to install the whole new beta of 2010.&lt;/P&gt;
&lt;P&gt;There are already many resources for learning F# including my &lt;A href="http://tomasp.net/blog/functional-overview.aspx"&gt;functional programming overview&lt;/A&gt;, which is a Manning Greenpaper for the book &lt;A href="http://www.functional-programming.net/"&gt;Functional Programming for the Real World&lt;/A&gt; that I'm writing with Jon Skeet and my &lt;A href="http://tomasp.net/blog/fsharp-i-introduction.aspx"&gt;four-part F# introduction&lt;/A&gt;. There are also some useful links on the official &lt;A href="http://www.fsharp.net/"&gt;F# web site&lt;/A&gt; including some talk recordings. However, I haven't yet seen any good F# webcast focusing mainly on showing F# source code, starting from simple functional concepts to the real-world features like asynchronous workflows and object-oriented programming in F#, so I decided to create one.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;(The whole webcast series is available in &lt;/EM&gt;&lt;A href="http://tomasp.net/blog"&gt;&lt;EM&gt;my other blog&lt;/EM&gt;&lt;/A&gt;&lt;EM&gt; and I'm cross-posting the links and brief descriptions of each of the parts here)&lt;/EM&gt;&lt;/P&gt;
&lt;H2&gt;The F# development process&lt;/H2&gt;
&lt;P&gt;The webcast&amp;nbsp;starts by experimenting with F# and by introducing some of the essential functional concepts and then follows the usual F# development process. It starts by creataing an empty F# script (&lt;EM&gt;New File... -&amp;nbsp;F# Script File &lt;/EM&gt;in Visual Studio), which is the easiest way to start coding in F#. We'll just create an empty script, start writing the code and run it interactively to see how it works. This way, we'll develop a very simple F# snippet for downloading content of a RSS feed and for searching for feeds that contain the specified keyword.&lt;/P&gt;
&lt;P&gt;Once we have a simple solution to the problem, we can start improving it and &lt;EM&gt;refactoring &lt;/EM&gt;it in various ways. I believe that refactoring is a very important part of the usual F# development process. In particular, we'll see how to wrap the code into asynchronous workflows to make it run asynchronously (rather than using blocking calls) and also potentially in parallel (rather than downloading and processing all the feeds in sequence).&lt;/P&gt;
&lt;P&gt;Finally, in the last part of the series, you'll see one more refactoring. We'll wrap the existing code into a simple&amp;nbsp;object oriented library and we'll also finally turn it from a simple F# script file into a standard .NET DLL library that can be used from C#. As you'll see in the webcast, this is again a relatively simple refactoring that includes only a couple of minor changes in the source code. Once we'll compile the library, we'll also look how to use it from C# and in particular, from a simple ASP.NET web application.&lt;/P&gt;
&lt;H2&gt;Introducing F# webcast&lt;/H2&gt;
&lt;P&gt;The links to the individual parts of the webcast are available here. Each of the articles also contains link for downloading the video (in case you wanted to view it offline) and also full source code that I wrote during the presentation:&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="MARGIN-BOTTOM: 5px"&gt;&lt;STRONG&gt;&lt;A href="http://tomasp.net/blog/fsharp-webcast-functional.aspx"&gt;Part I. - Introducing functional concepts&lt;/A&gt;&lt;/STRONG&gt;&lt;BR&gt;The first part introduces functional programming principles such as immutability, recursion and functions that take other functions as parameter (&lt;EM&gt;higher order&lt;/EM&gt; functions). This can all be demonstrated in C# 3.0, so we start with C# and then look how the same concepts look in F#. Finally, the first part also shows functions for working with lists in F#. 
&lt;LI style="MARGIN-BOTTOM: 5px"&gt;&lt;STRONG&gt;&lt;A href="http://tomasp.net/blog/fsharp-webcast-dotnet.aspx"&gt;Part II. - Using standard .NET libraries&lt;/A&gt;&lt;/STRONG&gt;&lt;BR&gt;The second part demonstrates how we can use standard .NET libraries. It uses classes from &lt;CODE&gt;System.Net&lt;/CODE&gt; and &lt;CODE&gt;System.Xml&lt;/CODE&gt; to download content of a web page (RSS feed), load it into XML document and process it to find only posts that contain some specified keyword. 
&lt;LI style="MARGIN-BOTTOM: 5px"&gt;&lt;STRONG&gt;&lt;A href="http://tomasp.net/blog/fsharp-webcast-async.aspx"&gt;Part III. - Downloading web pages asynchronously&lt;/A&gt;&lt;/STRONG&gt;&lt;BR&gt;The third part shows how to make the code from the part II. better. It introduces F# &lt;EM&gt;asynchronous workflows&lt;/EM&gt; that can be used for writing code that doesn't block a thread when waiting for the completion of some I/O request. This part also shows how to modify the code to download and process multiple feeds in parallel. 
&lt;LI style="MARGIN-BOTTOM: 5px"&gt;&lt;STRONG&gt;&lt;A href="http://tomasp.net/blog/fsharp-webcast-objects.aspx"&gt;Part IV. - Developing standard .NET libraries&lt;/A&gt;&lt;/STRONG&gt;&lt;BR&gt;In the fourth part, we look how to encapsulate the functionality written in F# into classes. We'll create a project and we'll wrap the code we wrote into a .NET class. We'll also look how to compile the project into DLL and how to use it from a simple C# web application.&lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=10966" width="1" height="1"&gt;</description></item><item><title>Visual Studio 2010 Beta1 with F# is now available, plus matching F# CTP Update for VS2008</title><link>http://cs.hubfs.net/blogs/f_team/archive/2009/05/20/10398.aspx</link><pubDate>Wed, 20 May 2009 19:53:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:10398</guid><dc:creator>dsyme</dc:creator><slash:comments>3</slash:comments><description>&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;&lt;o:p&gt;&lt;EM&gt;Cross posted from &lt;A href="http://blogs.msdn.com/dsyme/archive/2009/05/20/visual-studio-2010-beta1-with-f-is-now-available-plus-matching-f-ctp-update-for-vs2008.aspx"&gt;blogs.msdn.com&lt;/A&gt;&lt;/EM&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;&lt;o:p&gt;&lt;EM&gt;&lt;/EM&gt;&lt;/o:p&gt;&lt;/SPAN&gt;
&lt;P class='MsoNormal"'&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;The F# team are thrilled to announce that &lt;A class="" href="http://www.microsoft.com/visualstudio/en-us/products/2010/default.mspx"&gt;Visual Studio 2010 Beta1 is now available&lt;/A&gt;&amp;nbsp;, including the latest version of F#. Today we are also releasing a matching &lt;A class="" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=7bb32f32-9fac-4f34-ad56-b0bda130cf00"&gt;F# May 2009 CTP&lt;/A&gt; for use with Visual Studio 2008 (&lt;A class="" href="http://download.microsoft.com/download/F/7/4/F74A3170-261C-4E8F-B1A8-2E352C61A89B/InstallFSharp.msi"&gt;MSI&lt;/A&gt;, &lt;A class="" href="http://download.microsoft.com/download/F/7/4/F74A3170-261C-4E8F-B1A8-2E352C61A89B/fsharp.zip"&gt;ZIP&lt;/A&gt;).&amp;nbsp;Further below is&amp;nbsp;a &lt;A class="" href="http://blogs.msdn.com/dsyme/attachment/9632643.ashx"&gt;screen shot&lt;/A&gt;, more &lt;A class="" href="http://blogs.msdn.com/jasonz/archive/2009/05/18/announcing-vs2010-net-framework-4-0-beta-1.aspx"&gt;here&lt;/A&gt;.&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;&lt;/P&gt;
&lt;P class='MsoNormal"'&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;If you’re new to F#, consider watching the &lt;A href="http://channel9.msdn.com/pdc2008/TL11/"&gt;&lt;FONT color=#0000ff&gt;PDC presentation on F# by Luca Bolognese&lt;/FONT&gt;&lt;/A&gt;, and the live demo of F# and other new language technologies at JAOO by &lt;A href="http://jaoo.blip.tv/file/1317881/"&gt;&lt;FONT color=#0000ff&gt;Anders Hejlsberg, Where are Programming Languages Going&lt;/FONT&gt;&lt;/A&gt;, or else download,&amp;nbsp;start playing and take the &lt;A class="" href="http://msdn.microsoft.com/en-us/library/dd867745.aspx"&gt;MSDN walkthrough of F# in Visual Studio 2010&lt;/A&gt;.&lt;/SPAN&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;This release is a landmark in the process of making F# a &lt;B&gt;language officially supported by Microsoft&lt;/B&gt;, being the first release where &lt;B&gt;F# installs as part of Visual Studio 2010&lt;/B&gt;. Using Visual Studio 2010 you can build F# applications for &lt;A href="http://www.microsoft.com/net/"&gt;.NET 4.0&lt;/A&gt; Beta1, which has been released today. Likewise, using the F# CTP Update for Visual Studio 2008, you can build F# applications for .NET 2.0/3.0 and 3.5. The F# language itself is the same in both releases, with some &amp;nbsp;additional library functions (e.g. &lt;B&gt;Array.Parallel.map&lt;/B&gt;) available with .NET 4.0/Visual Studio 2010 Beta1 (see the &lt;A href="http://blogs.msdn.com/dsyme/archive/2009/05/20/detailed-release-notes-for-the-f-may-2009-ctp-update-and-visual-studio-2010-beta1-releases.aspx"&gt;&lt;FONT color=#0000ff&gt;detailed release notes&lt;/FONT&gt;&lt;/A&gt;). &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;As with our previous CTP release, one team focus of the last 6 months has been on &lt;B&gt;refining the F# language&lt;/B&gt; and &lt;STRONG&gt;taking feedback from the wonderful and growing F# community&lt;/STRONG&gt;.&amp;nbsp;For example, we have now made the F# lightweight syntax option the default for the language (i.e. for .fs/.fsi/.fsx files). We have added support for custom numeric type literals, which allows F# to &lt;B&gt;interoperate nicely with the BigInteger type on .NET 4.0&lt;/B&gt;, and have improved aspects of .NET interoperability such as &lt;B&gt;smoother calling of .NET param array methods&lt;/B&gt;.&amp;nbsp;You can also use F#'s support for &lt;B&gt;units-of-measure&lt;/B&gt; with integer types, e.g. to qualify integer types by annotations such as &amp;lt;Pixels&amp;gt; or &amp;lt;Clicks&amp;gt;. Additionally, we have been focusing on the &lt;B&gt;performance of F# language constructs&lt;/B&gt; in this release. In particular, we have made &lt;B&gt;performance improvements to F# sequence expressions&lt;/B&gt;, using a state machine compilation for sequence expressions that provides substantial performance improvements for code that generates data using these constructs. Similarly, if you disassemble some F# code you will notice that &lt;B&gt;F# classes have compact representations&lt;/B&gt;, and that some other constructs such as F# members taking arguments in curried form are compiled more efficiently. Taken together our aim has been to ensure a predictability in the performance characteristics of related language constructs. More detail in the &lt;A href="http://blogs.msdn.com/dsyme/archive/2009/05/20/detailed-release-notes-for-the-f-may-2009-ctp-update-and-visual-studio-2010-beta1-releases.aspx"&gt;&lt;FONT color=#0000ff&gt;detailed release notes&lt;/FONT&gt;&lt;/A&gt;.&lt;B&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/B&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;One area we have done considerable work is the &lt;B&gt;F# library&lt;/B&gt;, and existing users will notice this when they move their code to this release. The consistent feedback we've had is that the F# library support must be &lt;B&gt;consistent&lt;/B&gt; , &lt;B&gt;powerful&lt;/B&gt; and &lt;B&gt;simple&lt;/B&gt; to use. As a result, we have completed an end-to-end review of the library and made some revisions to ensure &lt;B&gt;standard naming conventions&lt;/B&gt; and &lt;B&gt;standard, simpler operator names&lt;/B&gt; . The library also now uses &lt;B&gt;uppercase type variable names&lt;/B&gt;. More details are available in the detailed release notes, including details of two small breaking changes and some simple ways to cope with these. The Visual Studio 2008 release also provides versions of FSharp.Core.dll to use when developing F# applications for Silverlight 2.0 and the .NET Compact Framework 2.0/3.5. &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;This release also sees major improvements in &lt;B&gt;F# debugging&lt;/B&gt;. First, in Visual Studio 2010 F# benefits from amazing new technology such as &lt;U&gt;&lt;A href="http://www.infoq.com/news/2009/04/LangNET-Debugging"&gt;time-travel debugging&lt;/A&gt;&lt;/U&gt; (ok, it’s officially called &lt;U&gt;&lt;A href="http://www.infoq.com/news/2009/04/LangNET-Debugging"&gt;historical debugging&lt;/A&gt;,&lt;/U&gt; but I grew up in the &lt;A href="http://www.bbc.co.uk/doctorwho/classic/"&gt;eighties&lt;/A&gt;). This a product-quality realization of a long term dream of many language implementations. Next, in both Visual Studio 2008 and Visual Studio 2010 you will see major &lt;B&gt;improvements in data visualization for F# language constructs&lt;/B&gt; such as records and discriminated unions and F# library types such as lists, maps and sets. &lt;B&gt;Breakpoint and stepping&lt;/B&gt; have also greatly improved, and in Visual Studio 2010 breakpoints can be more accurately positioned inside lambda functions. Some library support also aids in adhoc debugging, e.g. the printf format "%+A" can now be used to print the private, internals of and F# structured object (when running code as full-trust), and a width parameter can be specified to fit the formatted text within a visual display, e.g. "%+128A". &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;We have not neglected the &lt;B&gt;F# Language Service and F# Project System&lt;/B&gt;. For example, when you build from Visual Studio you will notice that the error list is now populated with errors from the build process. We have also made many performance and reactivity improvements to the F# language service, eliminating points where the Visual Studio user interface became less reactive due to background computations and increasing the number of cases where intellisense is made available. There are also nice additional touches for &lt;B&gt;scripting with F#&lt;/B&gt;, such as hovering over a #r declaration now reveals the exact resolution of an assembly reference.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;Next, we now have preliminary &lt;B&gt;documentation for the F# language&lt;/B&gt; on the MSDN website (yippee!). These are preliminary, and yes there are glitches, so please have patience and send us your feedback &lt;/SPAN&gt;&lt;FONT face=Tahoma&gt;&lt;SPAN style="FONT-FAMILY: Wingdings; mso-ansi-language: EN-US; mso-ascii-font-family: Calibri; mso-hansi-font-family: Calibri; mso-char-type: symbol; mso-symbol-font-family: Wingdings"&gt;&lt;SPAN style="mso-char-type: symbol; mso-symbol-font-family: Wingdings"&gt;J&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt; There is also a minor known bug in the walkthroughs where the code snippets all have extra leading whitespace.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Since F# is whitespace-significant by default, be sure to delete this leading whitespace when copying snippets.&amp;nbsp; These new docs are another good F# reference, as well as a resource for getting started with the language.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;Finally, we have done considerable work towards &lt;B&gt;aligning F# with .NET 4.0 additions&lt;/B&gt; , with the aim of ensuring a &lt;B&gt;long, bright, compatible future for functional, reactive and parallel programming on the .NET platform&lt;/B&gt;. For example, you will see that when using .NET 4.0, F# record, tuple and union types now implement the .NET 4.0 standard types IStructuralEquatable and IStructuralComparable. Furthermore F# tuples are compiled using the standard .NET 4.0 type &lt;B&gt;System.Tuple&lt;/B&gt;. We've also added some lovely operators to the F# library for .NET 4.0, in the Microsoft.FSharp.Collections.Array.Parallel module, building on the .NET Parallel Extensions library. For example Array.Parallel.map can be used to perform a parallel map of a function over a large data array. Finally, you'll notice the addition of &lt;B&gt;Async.CreateAsTask&lt;/B&gt; and the extension property .&lt;B&gt;AwaitTask&lt;/B&gt; as ways to create and wait for .NET 4.0 tasks, meaning you can program .NET tasks directly using the F# asynchronous programming support! &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="COLOR: #1f497d; mso-ansi-language: EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;IMG title="Screen Shot VS2010 Beta1" style="WIDTH: 769px; HEIGHT: 665px" height=665 alt="Screen Shot VS2010 Beta1" src="http://blogs.msdn.com/dsyme/attachment/9632643.ashx" width=769 align=top&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;&lt;A href="http://blogs.msdn.com/blogfiles/jasonz/WindowsLiveWriter/aeaf13805930_AB66/image_24.png"&gt;&lt;FONT color=#0000ff&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto"&gt;&lt;SPAN style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman','serif'; mso-ansi-language: EN-US"&gt;&lt;o:p&gt;&lt;FONT face=Tahoma size=2&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;&lt;FONT face=Tahoma size=2&gt;Details of all this and more is in the &lt;/FONT&gt;&lt;A href="http://blogs.msdn.com/dsyme/archive/2009/05/20/detailed-release-notes-for-the-f-may-2009-ctp-update-and-visual-studio-2010-beta1-releases.aspx"&gt;&lt;FONT face=Tahoma color=#0000ff size=2&gt;detailed release notes&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Tahoma size=2&gt;, and look for more blogging by the F# team and &lt;/FONT&gt;&lt;A href="/forums"&gt;&lt;FONT face=Tahoma color=#0000ff size=2&gt;community&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Tahoma&gt;&lt;FONT size=2&gt; about all this and more. As always we are very glad to hear your feedback on all aspects of F#, and the above updates especially. We trust you enjoy your F# programming!&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;&lt;o:p&gt;&lt;FONT face=Tahoma size=2&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;SPAN style="mso-ansi-language: EN-US"&gt;&lt;FONT face=Tahoma size=2&gt;Don Syme, for the F# team&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=10398" width="1" height="1"&gt;</description></item><item><title>hubFS:  Downtime notification</title><link>http://cs.hubfs.net/blogs/thepopeofthehub/archive/2009/04/10/hubFSDowntime20090410.aspx</link><pubDate>Fri, 10 Apr 2009 08:18:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:9875</guid><dc:creator>optionsScalper</dc:creator><slash:comments>1</slash:comments><description>&lt;P&gt;I've been informed by my hosting provider that the data centers where hubFS is hosted will be having scheduled maintenance, potentially causing downtime.&lt;/P&gt;
&lt;P&gt;This maintenance will occur Friday evening (4/10/2009 after 5pm CDT) and Saturday Daytime (4/11/2009).&amp;nbsp; While I don't have exact times, the outage is expected to be minimal and is unavoidable.&lt;/P&gt;
&lt;P&gt;My apologies in advance for the short notification and any issues that arise.&amp;nbsp; Leave comments on this post for any conditions that I can address if the downtime has affected posts.&lt;/P&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=9875" width="1" height="1"&gt;</description><category domain="http://cs.hubfs.net/blogs/thepopeofthehub/archive/category/1000.aspx">Hubology</category></item><item><title>My book: Real-world Functional Programming in .NET</title><link>http://cs.hubfs.net/blogs/tomasp/archive/2008/11/05/functional_book.aspx</link><pubDate>Wed, 05 Nov 2008 01:09:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:7614</guid><dc:creator>tomasp</dc:creator><slash:comments>1</slash:comments><description>&lt;P&gt;&lt;EM&gt;(This article is based on &lt;A href="http://tomasp.net/blog/functional-programming-book.aspx"&gt;two&lt;/A&gt; &lt;A href="http://tomasp.net/blog/functional-net-update.aspx"&gt;articles&lt;/A&gt; about the book that I posted to my &lt;A href="http://tomasp.net/blog"&gt;other blog&lt;/A&gt;).&lt;/EM&gt;&lt;/P&gt;&lt;IMG style="MARGIN: 10px; FLOAT: right" alt="Book cover" src="http://www.tomasp.net/img/cover_main.gif"&gt; 
&lt;P&gt;If you’ve been reading my blog or seen some my articles, you know that I’m a big fan of the F# language and functional programming style. I’m also often trying to present a bit different view of C# and LINQ – for me it is interesting mainly because it brings many functional features to a main-stream language and allows using of many of the functional patterns in a real-world. Elegant way for working with data, which is the most commonly used feature of C# 3.0, is just one example of this functional approach. Talking about real-world applications of functional programming, there is also fantastic news about F#. It was announced last year that F# will become fully supported Visual Studio language and the first September CTP version of F# was released recently! &lt;/P&gt;
&lt;P&gt;I always thought that the topics mentioned in the previous paragraph are really interesting and that functional programming will continue to become more and more important. That’s why I’m really excited that I have the privilege to write a book about these topics. The book is called &lt;A href="http://www.manning.com/petricek"&gt;Real-world Functional Programming in .NET&lt;/A&gt; [&lt;A target=_blank href="http://www.manning.com/petricek"&gt;^&lt;/A&gt;] and it’ll be published by &lt;A href="http://www.manning.com/"&gt;Manning Publications&lt;/A&gt; [&lt;A target=_blank href="http://www.manning.com/"&gt;^&lt;/A&gt;]. Even though there are some books about F# already (and more are probably comming soon), I believe that my book is unique in a way that it talks about both C# and F#. This is useful when understanding functional programming concepts, because you can see how would the same thing look in C#. Also, there are many functional techniques that can help you with daily C# programming and these are also discussed in the book. Here is a couple of reasons why you should have this book on your bookshelf:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Ideas behind C# 3.0 and LINQ&lt;/STRONG&gt; - these main-stream technologies are inspired by functional programming and the new C# 3.0 features give us definitely much more than just a new way to query databases. The book explains the ideas behind these features and shows how to use them more efficiently in a wider range of scenarios. 
&lt;LI&gt;&lt;STRONG&gt;Learning the F# language&lt;/STRONG&gt; - &lt;A href="http://blogs.msdn.com/somasegar/archive/2007/10/17/f-a-functional-programming-language.aspx"&gt;F# is becoming a first-class citizen&lt;/A&gt; [&lt;A target=_blank href="http://blogs.msdn.com/somasegar/archive/2007/10/17/f-a-functional-programming-language.aspx"&gt;^&lt;/A&gt;] in the Visual Studio family of languages, which alone would be a good reason for learning it! Even if you're not going to use it for your next large .NET project, you'll find it useful for quick prototyping of ideas and testing how .NET libraries work thanks to the great interactive tools. 
&lt;LI&gt;&lt;STRONG&gt;Real world examples&lt;/STRONG&gt; - the book includes a large set of real-world examples that show how to develop real .NET applications in a functional way - both in F# and C#. Among other things, the examples show how to utilize multi-core CPUs, how to better obtain and process data and how to implement animations and GUI applications in a functional way.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;To summarize, the goal of the book is to explain the key ideas of functional programming to real world .NET developers in a way they can benefit from them. It actually very much follows my personal experience – I started seriously looking at functional programming in the F# language after using primarily C# for quite a long time. &lt;/P&gt;
&lt;H2&gt;What's new?&lt;/H2&gt;
&lt;P&gt;Here is a couple of links if you're interested in more information about the book. I started a companion web site for the book, so you'll find everything regarding the book, links to related articles and the source code here: &lt;A style="FONT-WEIGHT: bold" href="http://www.functional-programming.net/"&gt;www.functional-programming.net&lt;/A&gt;. There is a book page at Manning web site where you can find the direct links to the free content (Chapter 1 and the Greenpaper) and also the option to purchase the book via MEAP today:&lt;/P&gt;
&lt;UL style="MARGIN-TOP: 0px"&gt;
&lt;LI&gt;&lt;A href="http://www.manning.com/petricek/"&gt;First four chapters&lt;/A&gt; are already available via Manning Early Access program. 
&lt;LI&gt;&lt;A href="http://www.manning.com/petricek/"&gt;First chapter&lt;/A&gt; titled "Thinking differently about problems" is available for free. 
&lt;LI&gt;&lt;A href="http://www.manning.com/free/green_petricek.html"&gt;Greenpaper&lt;/A&gt; showing what you can expect to find in the book is available for free. 
&lt;LI&gt;&lt;A href="http://www.functional-programming.net/"&gt;www.functional-programming.net&lt;/A&gt; - My web site about the book.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The MEAP program allows you to get the book now and start reading chapters as they become available. Once the whole book is completed, you'll get the final version (either electronic or both electronic and printed). This means that you'll be among the first people to see the draft and you also have a chance to influence it. I've been receiving a large number of great suggestions as well as corrections from the MEAP program via &lt;A href="http://www.manning-sandbox.com/forum.jspa?forumID=460"&gt;book forum at Manning&lt;/A&gt; [&lt;A target=_blank href="http://www.manning-sandbox.com/forum.jspa?forumID=460"&gt;^&lt;/A&gt;], so huge thanks to anyone who is reading the book and discussing it there!&lt;/P&gt;
&lt;P&gt;The MEAP version is updated every couple of weeks, so things has changed since I posted the announcement to my blog and I had to rewrite this paragraph. Currently, you can get first 10 chapters and I'm working on chapter 11, so you can see that there is very small delay (when I see some of the errors in the draft that readers report in the forum, I sometimes think that it is almost &lt;EM&gt;too small&lt;/EM&gt; - thanks again)!&lt;/P&gt;
&lt;P&gt;About a month ago, the MEAP version of the book was first in the list of Manning bestsellers (even before books on topics like ASP.NET "MVC" and Silverlight, which was a very nice surprise for me)! Click on the image to see the full-size screenshot:&lt;/P&gt;
&lt;DIV style="TEXT-ALIGN: center"&gt;&lt;A target=_blank href="http://tomasp.net/articles/functional-net-update/screen.png"&gt;&lt;IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; MARGIN-LEFT: auto; BORDER-TOP: 0px; MARGIN-RIGHT: auto; BORDER-RIGHT: 0px" alt="MEAP books" src="http://tomasp.net/articles/functional-net-update/screen_sm.png"&gt;&lt;/A&gt;&lt;/DIV&gt;
&lt;H2&gt;What’s inside?&lt;/H2&gt;
&lt;P&gt;The most interesting thing for me about writing the book is that I really had to shape my ideas very clearly and find a good way to organize all the topics. One point of view that I found particularly useful (and it reflects how I write code in F#) is that F# gives you a way to start with a very simple, easy to write and clear code and later turn it into a robust .NET code. At the beginning you can write your code just as a script for F# interactive using only the basic functional features. Thanks to the type inference the code is also very succinct. In the later phase you can use features like abstract interface types and object expressions to organize the code and make it easily accessible for example from C#. The nice thing is that the transition is very smooth, so you don't have to rewrite almost any code. &lt;/P&gt;
&lt;P&gt;Since many of the functional features are now available in C# 3.0, it is possible to apply some of these ideas to C# too. In particular, we can simplify many object-oriented constructs (including some well known design patterns) and also use many effective functional techniques. This way of thinking is very suitable for a book, because we can start by looking at simple and clear ideas and then learn more sophisticated techniques and language features. The chapters that are currently written follow this organization. Here is a brief overview of the content of every chapter:&lt;/P&gt;
&lt;H4&gt;Part I. Introduction&lt;/H4&gt;
&lt;P&gt;To many of the readers, functional programming is a completely new idea. The basic principles of functional programming are also quite different to what you may be used to. The first part of the book (containing chapters 1 - 4) serves as an introduction and touches lightly some of the ideas that will later become essential. &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Chapter 1: Thinking differently about problems&lt;/STRONG&gt; starts with a little section about the long history of functional programming (By the way, would you believe that the first functional programming language celebrated its 50 years in 2008?). As a next thing, the chapter discusses some important reasons why functional concepts are important nowadays and shows successful real world applications of these concepts. The largest part is a tasting of what you'll find later in the book and finally, it contains a section showing the first example application in F#. 
&lt;UL&gt;
&lt;LI style="MARGIN: 5px"&gt;The chapter is available for free from the &lt;A href="http://www.manning.com/petricek/"&gt;Manning book page&lt;/A&gt; [&lt;A target=_blank href="http://www.manning.com/petricek/"&gt;^&lt;/A&gt;]. &lt;/LI&gt;&lt;/UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Chapter 2: Functional concepts and programming languages&lt;/STRONG&gt; introduces the concepts behind functional programming. As I already mentioned many of the functional concepts are different then what you might be used to, so this chapter gives a brief overview (without any details) showing how functional concepts relate and what they mean for the program structure. 
&lt;LI&gt;&lt;STRONG&gt;Chapter 3: Meet tuples, lists and functions in F# and C#&lt;/STRONG&gt; finally shows some real functional code. In this chapter, we use both C# and F# when writing any code, which makes it easier to understand what the functional program does. It demonstrates some basic data types used in F# (such as tuples and lists) and also shows how they can be implemented in C#. This chapter also introduces the idea of using functions as values, which is one of the key functional concepts. 
&lt;LI&gt;&lt;STRONG&gt;Chapter 4: Exploring F# and .NET libraries by example&lt;/STRONG&gt; presents the first real world application implemented in F# and shows how to use various .NET and F# libraries from the F# language. We look at an application that loads data from a file and presents them in a graphical form using a pie chart. This chapter finishes the introductory part by presenting the F# language by example, using only basic features from Chapter 3.&lt;/LI&gt;&lt;/UL&gt;
&lt;H4&gt;Part II. Core functional techniques&lt;/H4&gt;
&lt;P&gt;The second part starts describing the "iterative development style" enabled by functional programming in F#. It discusses elementary ways used to construct functional programs. These give us a very clear and concise way to think about problems. Finally, in the later chapters it talks about functional applications from a higher perspective focusing more on architectural acpects.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Chapter 5: Creating and using common functional values&lt;/STRONG&gt; - in functional programming, applications are described more like calculations that take some values as arguments and return a value as a result. This chapter explains what values actually are and talks about usual ways to construct them. This includes representing multiple values, alternative values and also functions (which are values too). 
&lt;LI&gt;&lt;STRONG&gt;Chapter 6: Working with values using high-order functions&lt;/STRONG&gt; introduces better way for working with basic values from Chapter 5. Instead of manipulating with them directly, we can factor out the changing part of some common operation and then use the single function for many varying tasks. This talks mainly about using functions as arguments, which is also very important for C# 3.0, which supports lambda functions. 
&lt;LI&gt;&lt;STRONG&gt;Chapter 7: Designing data-centric programs&lt;/STRONG&gt; - when designing an application in the functional style, we start by thinking about the data that it works with. This principle is very useful and clear independently of the language that you're actually using. In this chapter, we demonstrate this principle and also show how it relates to some well-known structural design patterns. 
&lt;LI&gt;&lt;STRONG&gt;Chapter 8: Designing behavior-centric programs&lt;/STRONG&gt; - not all applications are primarily focused at working with data as described in Chapter 7. Here we talk about the second types of applications. Using functional terminology, this chapter talks about functions in detail. In the object oriented terminology, we look at some behavioral design patterns like Strategy or Command.&lt;/LI&gt;&lt;/UL&gt;
&lt;H4&gt;Part III.&lt;/H4&gt;
&lt;P&gt;This section focuses on more advanced concepts that are used later in the "iterative development style". Once the application or a library grows larger, we want to use various .NET facilities to organize it intuitively, expose it to other .NET languages and document it. If the library is intended only for F# then we can leverage of some advanced F# features. Finally, we also want to make the code more efficient by using general functional and F# specific optimization techniques.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Chapter 9: Turning values into F# object types with members&lt;/STRONG&gt; shows how to mix object-oriented and functional style of programming in F#. It shows how the functional concepts (like immutability) can be used well together with object oriented features like encapsulation and how the conceptually simple ideas from Chapter 7 and 8 can be wrapped into real-world .NET code. 
&lt;LI&gt;&lt;STRONG&gt;Chapter 10: Efficiency of data structures, tail-recursion and continuations&lt;/STRONG&gt; - in the earlier chapters we talked about recursion and data structures such as lists or trees. In this chapter, we look how to use them efficiently. This means how to avoid stack overflow errors when writing functional code and how to write fast code that processes lists and other collections. 
&lt;LI&gt;&lt;STRONG&gt;Chapter 11: Refactoring functional programs and using lazy values&lt;/STRONG&gt; Refactoring is a phase of development where we try to improve our code without doing any changes in its behavior. This is a very important step and functional programming gives us great tools to do it. Function values are useful when removing code duplication and thanks to immutablity it is much easier to ensure that a change will not affect the behavior. Finally, lazy values allow us to delay some computations until their results are actually needed, which is a topic very close to refactoring.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;These are all the chapters that I wrote already (Chapter 11 is not available yet, but I already know quite well what will be inside). I'll definitely blog about more chapters as I'll write them, so stay tuned for another update!&lt;/P&gt;
&lt;H3&gt;Looking for your feedback!&lt;/H3&gt;
&lt;P&gt;The book is still "work in progress", so I'm very glad to receive any feedback. I already got many useful comments and suggestions via the &lt;A href="http://www.manning-sandbox.com/forum.jspa?forumID=460"&gt;book forum at Manning&lt;/A&gt; [&lt;A target=_blank href="http://www.manning-sandbox.com/forum.jspa?forumID=460"&gt;^&lt;/A&gt;], from the reviewers of the first third of the book and also from my colleagues and friends. However, this is probably the first book about functional programming that aims to a very wide audience of .NET programmers, requiring only advanced C# background, so any comments are more than welcome! You can post them to the forum mentioned above as well as directly to me at &lt;A href="mailto:tomas@tomasp.net"&gt;tomas@tomasp.net&lt;/A&gt;.&lt;/P&gt;
&lt;H2&gt;More information&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://www.functional-programming.net/"&gt;Real-world Functional Programming in .NET&lt;/A&gt; [&lt;A target=_blank href="http://www.functional-programming.net/"&gt;^&lt;/A&gt;] - book homepage 
&lt;LI&gt;&lt;A href="http://www.manning.com/petricek/"&gt;Manning: Real-world Functional Programming in .NET&lt;/A&gt; [&lt;A target=_blank href="http://www.manning.com/petricek/"&gt;^&lt;/A&gt;] - book page at Manning.Com 
&lt;LI&gt;&lt;A href="http://www.manning-sandbox.com/forum.jspa?forumID=460"&gt;Forum dedicated to the book&lt;/A&gt; [&lt;A target=_blank href="http://www.manning-sandbox.com/forum.jspa?forumID=460"&gt;^&lt;/A&gt;] - at Manning.Com&lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=7614" width="1" height="1"&gt;</description></item><item><title>Amanda and Some Guy discuss F# on .NET Rocks!</title><link>http://cs.hubfs.net/blogs/thepopeofthehub/archive/2008/09/16/FSharpDotNetRocksAmandaTed.aspx</link><pubDate>Tue, 16 Sep 2008 21:30:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:7114</guid><dc:creator>optionsScalper</dc:creator><slash:comments>0</slash:comments><description>&lt;P&gt;Amanda Laucher and Ted Neward&amp;nbsp;talk about F# on&amp;nbsp;a recently released .NET Rocks! podcast (&lt;A href="http://www.dotnetrocks.com/default.aspx?showNum=377"&gt;episode 377&lt;/A&gt;).&amp;nbsp; Richard and Carl pose a lot of tough questions.&amp;nbsp; Amanda and Ted are up to the task and provide a great perspective on functional languages, OO, F#, .NET and many other things.&amp;nbsp; While I don't really know Ted, I can only help to perpetuate the "Some Guy" reference in the podcast.&amp;nbsp; Evidently Amanda and Ted are also working on a book "F# in a Nutshell".&lt;/P&gt;
&lt;P&gt;Amanda can be found at &lt;A href="http://www.pandamonial.com/"&gt;Pandamonial&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Ted can be found at &lt;A href="http://blogs.tedneward.com/"&gt;The Blog Ride&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Podcast is &lt;A href="http://www.dotnetrocks.com/default.aspx?showNum=377"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Good stuff.&lt;/P&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=7114" width="1" height="1"&gt;</description></item><item><title>F# September 2008 CTP Released</title><link>http://cs.hubfs.net/blogs/f_releases/archive/2008/09/05/6911.aspx</link><pubDate>Fri, 05 Sep 2008 05:55:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:6911</guid><dc:creator>optionsScalper</dc:creator><slash:comments>5</slash:comments><description>&lt;P&gt;The F# Team has released the F# September 2008 CTP.&amp;nbsp; Seeing F# followed by "CTP" is outstanding.&amp;nbsp; Congratulations to Don Syme and his team for steady and consistent work to move F# to another milestone.&lt;/P&gt;
&lt;P&gt;Read about it &lt;A href="http://blogs.msdn.com/dsyme/archive/2008/08/29/the-f-september-2008-ctp-is-now-available.aspx"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Download it &lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=61ad6924-93ad-48dc-8c67-60f7e7803d3c&amp;amp;displaylang=en"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=6911" width="1" height="1"&gt;</description></item><item><title>&amp;quot;F# for Scientists&amp;quot; now available</title><link>http://cs.hubfs.net/blogs/f_team/archive/2008/08/28/6744.aspx</link><pubDate>Thu, 28 Aug 2008 22:05:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:6744</guid><dc:creator>dsyme</dc:creator><slash:comments>2</slash:comments><description>&lt;P&gt;[ Cross posted from &lt;A href="http://blogs.msdn.com/dsyme/archive/2008/08/28/f-for-scientists-now-available.aspx"&gt;http://blogs.msdn.com/dsyme/archive/2008/08/28/f-for-scientists-now-available.aspx&lt;/A&gt;&amp;nbsp;]&lt;/P&gt;
&lt;P&gt;I can't believe I missed posting about this - &lt;A class="" href="http://www.wiley.com/WileyCDA/WileyTitle/productCd-0470242116.html"&gt;F# for Scientists&lt;/A&gt; is now out! &lt;/P&gt;
&lt;P&gt;I haven't got my hardcopy just yet, but I read a draft of this book, and was impressed. The 3D visualization chapter is stunning in its simplicity and power, the parallel programming techniques presented are simple and powerful, and the examples of interoperating with Mathematica, MATLAB and using web databases opened gateways to the crucial information sources and tools that form a significant part of modern computational science.&lt;/P&gt;
&lt;P&gt;Here's a snippet from an &lt;A class="" href="http://www.amazon.com/review/product/0470242116/ref=dp_top_cm_cr_acr_txt?%5Fencoding=UTF8&amp;amp;showViewpoints=1"&gt;Amazon review&lt;/A&gt;&amp;nbsp;attributed to&amp;nbsp;&lt;A class="" href="http://www.infoworld.com/article/07/06/06/23FEcto07-bernardin_1.html"&gt;Jamie Bernadin&lt;/A&gt;, who I understand is CTO of &lt;A class="" href="http://www.datasynapse.com/"&gt;Data Synapse&lt;/A&gt;:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;All round outstanding. I wish more books were written at this level of quality. While this book can be used by anybody that wants to get up to speed with F#, it's also well suited for use as a text book for an undergraduate course in applied math or computer science (or reference for a graduate course). It's well organized, well written, and draws from classic examples in mathematical computing. ...If you enjoy this type of stuff, it's an absolutely pleasure to read - logical in flow and well articulated.&amp;nbsp; ... a must-have book if you're doing anything with F# - or just considering it. &lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The soon-to-be-released&amp;nbsp;F# CTP will have some ground-breaking features for added power and correctness in programming in these domains - watch this space for more :-)&lt;/P&gt;
&lt;P&gt;Don Syme&lt;/P&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=6744" width="1" height="1"&gt;</description></item><item><title>Concurrency on a single thread</title><link>http://cs.hubfs.net/blogs/hell_is_other_languages/archive/2008/08/03/6506.aspx</link><pubDate>Sun, 03 Aug 2008 09:40:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:6506</guid><dc:creator>gneverov</dc:creator><slash:comments>9</slash:comments><description>&lt;H3&gt;Introduction&lt;/H3&gt;
&lt;P&gt;F# has the async computation expression for writing parallel programs. Async achieves concurrency by using the CLR ThreadPool to queue work items for each logical thread created in an async expression (e.g., through Async.spawn or Async.parallel). Using the thread pool is good because it reuses existing threads instead of creating and destroying new threads. However the thread pool has limitations when a large number of threads are created that may result in deadlock (if queued work items don't execute because of blocked threads), increased memory usage, and poorer performance due to excessive context switching.&lt;/P&gt;
&lt;P&gt;Suppose we want to write a parallel application that creates a large number of concurrently executing threads. Threads are good because they present a sequential control flow model that is easy to understand and reason about, and having a large number of threads facilitates better resource utilization. To do this we would like to implement our own scalable concurrent threading system for our application that uses virtual threads not backed by the CLR thread pool or OS threads. To enable scalability, the creation of virtual threads in the system will be cheap (about the cost of a newobj instruction) and not consume OS-level resources (and similarly for synchronization primitives also). &lt;/P&gt;
&lt;P&gt;The implementation of this system will be based on the standard F# async: it will be a computation expression based on the continuation monad and the users' code will look similar and be functionally the same. However operationally it will be different from the standard async because it will use a fixed number of threads instead of the thread pool. (For version 1 in this post it will use only 1 thread, but a version 2 might extend that to 1 thread per CPU.) &lt;/P&gt;
&lt;P&gt;You can download the F# code for this post &lt;A href="/blogs/hell_is_other_languages/attachment/6506.ashx"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;H3&gt;Scheduler&lt;/H3&gt;
&lt;P&gt;At the core of this new async monad is the thread scheduler. The scheduler makes multiple threads of execution and multiplexes them together to give the illusion of concurrency. The scheduler is entirely managed code and uses continuations to manipulate control flow. The state of the scheduler consists of three parts:&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;type&lt;/span&gt; Scheduler () = &lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; ready : LinkedList&amp;lt;unit -&amp;gt; unit&amp;gt;; &lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; pending : &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt; ref &lt;/span&gt;&lt;/P&gt;
&lt;P&gt;The ready queue is a list of continuations that represent threads ready to run. It is a LinkedList from the BCL to allow fast insertion/removal from the beginning and end of the list. The basic operation of the one real OS thread in the system is this loop below.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;rec&lt;/span&gt; loop () =&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; ready.Count &amp;gt; 0 &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;then&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; k = ready.Dequeue ()&lt;br /&gt;    k ()&lt;br /&gt;    loop ()&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;It checks to see if the ready queue is non-empty. If so, it removes the first continuation, executes it (which may modify the ready queue) and repeats. However asynchronous I/O operations complicate this simple algorithm.&lt;/P&gt;
&lt;H3&gt;Asynchronous I/O&lt;/H3&gt;
&lt;P&gt;An I/O operation (like reading or writing to a disk or network) can take a long time and during this time the CPU is idle. If we performed a blocking I/O operation on our one real thread then all virtual threads would be suspended – not good. Therefore it is imperative that the programmer using this async monad never uses blocking operations and always uses non-blocking I/O. Win32 supports non-blocking I/O called 'overlapped' I/O. The basic principle is that a thread makes a system call to start an I/O operation. The system call returns immediately before the operation is completed. The operation is performed by the OS and not on the process's thread. When the operation is complete, a callback is executed on one of the threads in the process. The key point here is that the non-blocking I/O operation didn't create or consume an OS thread, thereby by using this we can stick to our one-thread budget. Non-blocking I/O is exposed in the BCL through Begin/End methods on various I/O objects (FileStream, etc.) and on Windows these methods are probably implemented using Win32 overlapped I/O.&lt;/P&gt;
&lt;P&gt;The pending field in the state of the scheduler contains the number of logical threads currently in an asynchronous I/O operation. So when ready.Count = 0 and !pending = 0 the computation has terminated.&lt;/P&gt;
&lt;H3&gt;The Monad&lt;/H3&gt;
&lt;P&gt;So let's get started looking at the code. Additionally this will also serve as a guide to writing (not-necessarily-concurrency-related) computation expression builders in F#. The monad used in this code is based on the papers by &lt;A href="http://citeseer.ist.psu.edu/claessen99functional.html"&gt;Classen&lt;/A&gt;&amp;nbsp;and &lt;A href="http://www.cis.upenn.edu/~stevez/papers/LZ07.ps"&gt;Li and Zdancewic&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;The type of the monad used here is&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;type&lt;/span&gt; Async&amp;lt;'a&amp;gt; = Async of (Scheduler * ('a -&amp;gt; unit) * (exn -&amp;gt; unit) -&amp;gt; unit)&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;In general all F# monad types need to be function types to achieve the delayed evaluation implicit in a computation expression block. Furthermore you'd typically want to wrap this type in a discriminated union tag to aid type inference. Hence making the general form of a monad type&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;type&lt;/span&gt; M&amp;lt;'a&amp;gt; = M of (… -&amp;gt; …)&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;In the Async type the left of the function arrow takes three arguments: the state of the scheduler of type Scheduler, a success continuation of type ('a -&amp;gt; unit) and an exception continuation of type (exn -&amp;gt; unit).&lt;/P&gt;
&lt;P&gt;The Scheduler type was mentioned above. The Scheduler state supports the following operations.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;member&lt;/span&gt; QueueFirst : (unit -&amp;gt; unit) -&amp;gt; Lock&amp;lt;unit&amp;gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;member&lt;/span&gt; QueueLast : (unit -&amp;gt; unit) -&amp;gt; Lock&amp;lt;unit&amp;gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;member&lt;/span&gt; Dequeue : unit -&amp;gt; Lock&amp;lt;(unit -&amp;gt; unit) option&amp;gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;member&lt;/span&gt; IncrPending : unit -&amp;gt; Lock&amp;lt;unit&amp;gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;member&lt;/span&gt; DecrPending : unit -&amp;gt; Lock&amp;lt;unit&amp;gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;member&lt;/span&gt; Run : Lock&amp;lt;'a&amp;gt; -&amp;gt; 'a&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Since the Scheduler state will be accessed by two threads: the single application thread and the CLR IO completion thread, access to the data structure needs to be synchronized. This is done using the &lt;A href="/blogs/hell_is_other_languages/archive/2008/02/17/4892.aspx"&gt;lock monad&lt;/A&gt; from my previous blog post. &lt;/P&gt;
&lt;H3&gt;Return &amp;amp; Bind&lt;/H3&gt;
&lt;P&gt;We now implement the standard return and bind operations for a continuation monad.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; mreturn x = Async (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; (sched, sk, ek) -&amp;gt; sk x)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; apply (Async m) (sched, sk, ek) = m (sched, sk, ek)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; bind m f =&lt;br /&gt;  Async (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; (sched, sk, ek) -&amp;gt; &lt;br /&gt;    apply m (sched, (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; x -&amp;gt; apply (f x) (sched, sk, ek))&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;,&lt;/span&gt; ek))&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;The implementation of return is fine; however there is a problem with the implementation of bind because it does not take into account the possibility of exceptions. If the function f throws and exception then this must be caught somewhere and execution diverted to the exception continuation.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;type&lt;/span&gt; Result&amp;lt;'a&amp;gt; = Success of 'a &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Error of exn&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; tryApply f x = &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;try&lt;/span&gt; Success (f x) &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;with&lt;/span&gt; e -&amp;gt; Error e&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; apply2 f x (sched, sk, ek) = &lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;match&lt;/span&gt; tryApply f x &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;with&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Success m -&amp;gt; apply m (sched, sk, ek)&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Error e -&amp;gt; ek e&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; bind m f =&lt;br /&gt;  Async (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; (sched, sk, ek) -&amp;gt; &lt;br /&gt;    apply m (sched, (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; x -&amp;gt; apply2 f x (sched, sk, ek))&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;,&lt;/span&gt; ek))&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;The tryApply function will always be used whenever applying an "outside" function (a function defined outside the async library) so that any exceptions thrown by this function can be reified as values and control flow handled appropriately.&lt;/P&gt;
&lt;H3&gt;Mzero &amp;amp; Mplus&lt;/H3&gt;
&lt;P&gt;Two primitive operations for the async monad are stop and fork. The stop operation terminates the current thread. The fork operation duplicates the current thread and returns different values on each. For example, if there is a thread executing the expression "bind (fork m1 m2) f" then after the evaluation of fork there will be two threads executing: one executing the expression "bind m1 f" and the other executing "bind m2 f". Fork is the primitive method for creating new threads in the async monad. The implementation for stop and fork are as follows.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; stop =&lt;br /&gt;  Async (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; (sched, sk, ek) -&amp;gt; ())&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; fork m1 m2 = &lt;br /&gt;  Async (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; (sched, sk, ek) -&amp;gt; &lt;br /&gt;    sched.QueueLast (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; () -&amp;gt; apply m2 (sched, sk, ek)) |&amp;gt; sched.Run&lt;br /&gt;    apply m1 (sched, sk, ek))&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Unfortunately calling stop stops the current thread without running any finally handlers that are in scope. Ideally there should be a third continuation (called the finally continuation) that is executed by stop, but we'll ignore this issue for now. The fork operation works by queuing the second branch of the fork at the end of the scheduler's ready queue and executing the first branch immediately. Stop and fork form the mzero and mplus operations of a MonadPlus type class instance for the async monad.&lt;/P&gt;
&lt;H3&gt;Yield&lt;/H3&gt;
&lt;P&gt;The yield operation forces the thread to give up its execution and re-queues itself at the end of the ready queue.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; myield =&lt;br /&gt;  Async (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; (sched, sk, ek) -&amp;gt; &lt;br /&gt;     sched.QueueLast sk |&amp;gt; sched.Run)&lt;/span&gt;&lt;/P&gt;
&lt;H3&gt;Callback&lt;/H3&gt;
&lt;P&gt;The callback operation is used to invoke asynchronous IO operations. In the CLR base class library, asynchronous IO operations are defined by two methods: a Begin method and an End method (e.g. for reading from a stream BeginRead and EndRead). These two methods are passed to the callback function below. This function first increments the schedulers pending count to mark the start of a new asynchronous IO operation. It then calls the Begin method passing the function cb as the callback. If the Begin method was successful then this thread yields, otherwise the pending count is decremented and the exception continuation invoked. When the system has performed the IO operation it calls cb on some special thread (not the scheduler's thread). Therefore cb cannot continue execution of the continuation monad; instead it must marshal a continuation back onto the scheduler's ready queue. So it first calls the End method to get the result of the IO operation. If the IO operation failed for some reason then can exception will be thrown in this call. Depending on the success of End, either the success or exception continuation is chosen and queued at the front of the ready queue. The pending count is decremented and the lock is pulsed to wake up the scheduler thread which may be blocking waiting for new continuations to execute.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; callback : (AsyncCallback -&amp;gt; IAsyncResult) -&amp;gt; (IAsyncResult -&amp;gt; 'a) -&amp;gt; Async&amp;lt;'a&amp;gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; callback (beginFunc : _ -&amp;gt; IAsyncResult) endFunc =&lt;br /&gt;  Async (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; (sched, sk, ek) -&amp;gt; &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; cb (ar : IAsyncResult) = &lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; k = &lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;match&lt;/span&gt; tryApply endFunc ar &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;with&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Success x -&amp;gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; () -&amp;gt; sk x &lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Error e -&amp;gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; () -&amp;gt; ek e&lt;br /&gt;      lock { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt;! sched.QueueFirst k&lt;br /&gt;             &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt;! sched.DecrPending ()&lt;br /&gt;             return! Lock.pulseAll } |&amp;gt; sched.Run&lt;br /&gt;    sched.IncrPending () |&amp;gt; sched.Run&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;match&lt;/span&gt; tryApply beginFunc (AsyncCallback(cb)) &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;with&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Success ar -&amp;gt; ()          &lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Error e -&amp;gt; sched.DecrPending () |&amp;gt; sched.Run&lt;br /&gt;                   ek e)&lt;/span&gt;&lt;/P&gt;
&lt;H3&gt;Run&lt;/H3&gt;
&lt;P&gt;Finally, we need to run function to execute the async monad. The run function creates a new scheduler and a place to store results. When executing, an async computation may create multiple threads that terminate successfully (viz. without calling stop) and thereby producing multiple results (and exceptions). Therefore the result of executing an async computation is a list of Result values. An initial continuation is added to the ready queue that runs the target monad with success and exception continuations that add respectively to the result list. Continuations are then dequeued and run iteratively until there is no more work to do.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; run m = &lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; sched = &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;new&lt;/span&gt; Scheduler()&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; result = ref []&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; init () = apply m (sched, (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; x -&amp;gt; result &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;:=&lt;/span&gt; Success x :: !result)&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;,&lt;/span&gt; (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; e -&amp;gt; result &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;:=&lt;/span&gt; Error e :: !result))&lt;br /&gt;  sched.QueueFirst init |&amp;gt; sched.Run&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; f () = sched.Dequeue () |&amp;gt; sched.Run&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;for&lt;/span&gt; k &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;in&lt;/span&gt; Seq.unfold0 f &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt; k ()&lt;br /&gt;  !result&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Many applications however will expect a single result from an async computation, so the runOne function is also created to only return the first result.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; runOne m =&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;match&lt;/span&gt; run m &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;with&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; [] -&amp;gt; failwith &lt;span style="color: Red;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;"no value"&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Success x::_ -&amp;gt; x&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Error e::_ -&amp;gt; raise e&lt;/span&gt;&lt;/P&gt;
&lt;H3&gt;Synchronization&lt;/H3&gt;
&lt;P&gt;There needs to be some way for threads within an async computation to synchronize with each other. We can't use the CLR's synchronization primitives because they will block the scheduler thread; therefore we need to create our own. So we will create a manual reset event (and leave an auto reset event as an exercise for the reader).&lt;/P&gt;
&lt;P&gt;A manual reset event will be represented as an optional list of continuations. A value of None means that the event is in the signalled state. A value of Some ws means that the event is in the non-signalled state and the list ws contains the continuations waiting for the event to become signalled. Hence a value of Some [] means that the event is not signalled but no one is waiting on it. The type of a manual reset event is&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;type&lt;/span&gt; MRE = MRE of (unit -&amp;gt; unit) list option ref&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;To create a new MRE in the specified state &lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; newMRE state = &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; state &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;then&lt;/span&gt; MRE (ref None) &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;else&lt;/span&gt; MRE (ref (Some []))&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Waiting on a MRE causes its state to be analysed. Access to the MRE's internal mutable state does not need to be synchronized because there is only one real thread in the system. If it is signalled then the success continuation can be invoke immediately. If it is not signalled then the success continuation is added to the wait list and the thread yields.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; waitMRE (MRE mre) =&lt;br /&gt;  Async (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; (sched, sk, ek) -&amp;gt;&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;match&lt;/span&gt; !mre &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;with&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; None -&amp;gt; sk ()&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Some wait -&amp;gt; mre &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;:=&lt;/span&gt; Some (sk :: wait))&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;When setting an MRE, its state is again analysed. If it is already signalled then do nothing. Otherwise set the state to signalled and add each of the continuations in the wait list to the ready queue. Finally, regardless of the initial state, the success continuations in executed since setting an MRE is a non-blocking operation.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; setMRE (MRE mre) =&lt;br /&gt;  Async (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; (sched, sk, ek) -&amp;gt;&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;match&lt;/span&gt; !mre &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;with&lt;/span&gt;&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; None -&amp;gt; ()&lt;br /&gt;      &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Some wait -&amp;gt; mre &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;:=&lt;/span&gt; None&lt;br /&gt;                     Lock.iter (sched.QueueFirst) wait |&amp;gt; sched.Run&lt;br /&gt;    sk ())&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;As well as auto reset events, other synchronization primitives can also be defined, such as MVars.&lt;/P&gt;
&lt;H3&gt;Creating threads&lt;/H3&gt;
&lt;P&gt;In many applications fork is not a particularly intuitive operation. A spawn operation that takes an async computation executes it on a new thread and then ends that thread is more intuitive in many scenarios. We can write a spawn operation in terms of the primitives we have already defined.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; spawn m = &lt;br /&gt;  async { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; join = newMRE &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;false&lt;/span&gt;&lt;br /&gt;          return! fork (mreturn join) &lt;br /&gt;                       (async { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt;! tryWith m (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; _ -&amp;gt; mreturn ())&lt;br /&gt;                                &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt;! setMRE join&lt;br /&gt;                                return! stop }) }&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;spawn starts by creating a new MRE that will be used signal the end of the spawned thread. It then forks. To one thread it returns the MRE so the caller can synchronize on the completion of the spawned computation. The other thread executes the target computation expression, ignoring any exceptions raised, signals the MRE and terminates.&lt;/P&gt;
&lt;P&gt;One of the most useful async operations is parallel which takes a list of computations, executes them all in parallel and returns a list of their results.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; parallel ms =&lt;br /&gt;  async { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; results = Array.zero_create (List.length ms)&lt;br /&gt;          &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; task = &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; i m -&amp;gt; &lt;br /&gt;            async { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! x = m &lt;br /&gt;                    return results.[ i ] &amp;lt;- x } |&amp;gt; spawn&lt;br /&gt;          &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! joins = mapi task ms &lt;br /&gt;          &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt;! iter waitMRE joins&lt;br /&gt;          return results |&amp;gt; Array.to_list }&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;parallel first finds the length of the list and allocates an array to hold all the results. It then creates a task for each element in the list that executes the async computation and stores its result in the corresponding position in the results array. Spawning all these tasks produces a list of MREs which are used to wait for all the tasks to complete. When all the MREs have been signalled the function returns the list of results.&lt;/P&gt;
&lt;P&gt;Another useful control flow operation is first that evaluates a target computation (which may fork) but continues only with the first thread that completes. It creates a new ARE in the signalled state. The first thread that completes the computation will reset the ARE and return the result. Other threads will see the non-signalled ARE and terminate.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; first m =&lt;br /&gt;  async { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; once = newARE &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;true&lt;/span&gt;&lt;br /&gt;          &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! x = m&lt;br /&gt;          &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! b = tryWaitARE once&lt;br /&gt;          &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; b &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;then&lt;/span&gt; return x&lt;br /&gt;          &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;else&lt;/span&gt; return! stop }&lt;/span&gt;&lt;/P&gt;
&lt;H3&gt;Conclusion&lt;/H3&gt;
&lt;P&gt;This blog post is already long enough so I'll stop it here before covering applications. In the &lt;A href="/blogs/hell_is_other_languages/attachment/6506.ashx"&gt;code download&lt;/A&gt; you can find examples of a web crawler, image resizer and the concurrency example from this paper by &lt;A href="http://lampwww.epfl.ch/~odersky/papers/jmlc06.html"&gt;Haller and Odersky&lt;/A&gt;. Two natural extensions to the system presented here are making the scheduler (1) multi-threaded and (2) distributed. Using &lt;A href="http://msdn.microsoft.com/en-us/library/72hyey7b(VS.80).aspx)"&gt;.NET binary serialization&lt;/A&gt;&amp;nbsp;it should be possible to serialize the continuations as delegates and send them to a different process/host. Additionally the &lt;A href="/blogs/hell_is_other_languages/archive/2008/01/16/4565.aspx"&gt;STM monad&lt;/A&gt; could be built-in under the continuation monad as the primitive means for blocking, synchronization and inter-process communication.&lt;BR&gt;&lt;/P&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=6506" width="1" height="1"&gt;</description><enclosure url="http://cs.hubfs.net/blogs/hell_is_other_languages/attachment/6506.ashx" length="8359" type="application/x-zip-compressed" /></item><item><title>Investing in F# - Making the tools and language better still</title><link>http://cs.hubfs.net/blogs/f_team/archive/2008/07/26/6448.aspx</link><pubDate>Sat, 26 Jul 2008 16:50:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:6448</guid><dc:creator>dsyme</dc:creator><slash:comments>4</slash:comments><description>&lt;P&gt;The F# team at Microsoft Research and Microsoft are currently working hard&amp;nbsp;towards our planned&amp;nbsp;&lt;A href="http://blogs.msdn.com/dsyme/archive/2008/04/04/tackling-the-f-productization.aspx"&gt;CTP release of F#&lt;/A&gt;. This is a follow up to the &lt;A href="http://blogs.msdn.com/dsyme/archive/2008/05/02/f-1-9-4-now-available-making-f-simpler-and-more-consistent.aspx"&gt;1.9.4&lt;/A&gt; release of F# as a research language.&lt;/P&gt;
&lt;P&gt;When it comes, this&amp;nbsp;release will be the first release that includes signficant&amp;nbsp;improvements in the Visual Studio tools. &lt;A href="http://lorgonblog.spaces.live.com/"&gt;Brian McNamara&lt;/A&gt; has been posting &lt;A href="http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!282.entry"&gt;a few sneak screen shots of the project system in Visual Studio&lt;/A&gt;.&amp;nbsp;Watch Brian's blog for more!&lt;/P&gt;
&lt;P&gt;The project system isn't the only thing we're doing: we've done an end-to-end design review, some results&amp;nbsp;of which appeared in 1.9.4, we've got improvements to F# Interactive in Visual Studio, and there are&amp;nbsp;other&amp;nbsp;improvements across the board, as well as some great new productivity features. We look forward to your feedback when we role this release out, and we know it will make your use of F# more productive still.&lt;/P&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=6448" width="1" height="1"&gt;</description></item><item><title>F# Support for ASP.NET and Notes on Samples</title><link>http://cs.hubfs.net/blogs/tomasp/archive/2008/03/08/aspnet_in_fsharp.aspx</link><pubDate>Sat, 08 Mar 2008 22:36:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:5244</guid><dc:creator>tomasp</dc:creator><slash:comments>2</slash:comments><description>&lt;P&gt;&lt;EM&gt;(This article is cross-posted from &lt;/EM&gt;&lt;A href="http://tomasp.net/articles/aspnet-in-fsharp.aspx"&gt;&lt;EM&gt;http://tomasp.net/articles/aspnet-in-fsharp.aspx&lt;/EM&gt;&lt;/A&gt;&lt;EM&gt;)&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;As I mentioned earlier, I spent three months as an intern in Microsoft Research in Cambridge last year and I was working with Don Syme and James Margetson from the F# team. Most of the time I was working on the F# Web Toolkit, which I introduced on the blog some time ago [&lt;A&gt;1&lt;/A&gt;], but I also worked on a few additions that are now part of the F# release. Probably the most useful addition is a new implementation of the CodeDOM provider for the F# language which makes it possible to use ASP.NET smoothly from F# (but it can be used in some other scenarios as well) together with two ASP.NET sample applications that you can explore and use as a basis for your web sites. This was actually a part of the distribution for a few months now (I of course wanted to write this article much earlier...), so you may have already noticed, but anyway, I'd still like to write down a short description of these ASP.NET samples and also a few tips for those who're interested in writing web applications in F#. &lt;/P&gt;
&lt;H2&gt;F# and ASP.NET&lt;/H2&gt;
&lt;P&gt;Let's start by looking at the ASP.NET examples. You can find them in the &lt;CODE&gt;samples&lt;/CODE&gt; directory in your F# installation under the &lt;CODE&gt;Web/ASP.NET&lt;/CODE&gt; path. The directory also contains &lt;CODE&gt;html&lt;/CODE&gt; files with description of the projects and a guide to configuring them, but I'll describe both of these topics in this post. The distribution contains two sample projects: &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;AspNetIntro&lt;/STRONG&gt; - this project is (almost) the simples possible F# web site, so it can be used as a template for your web sites. It shows how to configure the CodeDOM provider, how to write a simple page with code-behind and how to use the &lt;CODE&gt;App_Code&lt;/CODE&gt; directory and data-binding. &lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PersonalWebSite&lt;/STRONG&gt; - this is a more complex web site ported from the C# sample called &lt;STRONG&gt;Personal Web Site Starter Kit&lt;/STRONG&gt; [&lt;A&gt;2&lt;/A&gt;]. It demonstrates many of the standard ASP.NET 2.0 techniques including data access controls, master pages, membership and custom HTTP handlers.&lt;/LI&gt;&lt;/UL&gt;
&lt;H2&gt;ASP.NET Introduction using F#&lt;/H2&gt;
&lt;P&gt;To start playing with ASP.NET you'll need to open the project (I recommend copying it to your working directory first). If you're using Visual Studio, you can select &lt;CODE&gt;File - Open - Web Site...&lt;/CODE&gt; in the menu and select the directory with your project as demonstrated at Figure 1 below. The organization of ASP.NET projects is different than organization of ordinary F# projects - in ASP.NET the project is just a directory and it contains all the files in the directory (this is also the reason why you have to open it using a different command). The Figure 2 shows how the files of the ASP.NET Introduction project are organized in the Solution Explorer: &lt;/P&gt;
&lt;DIV&gt;
&lt;DIV style="MARGIN-LEFT: auto; WIDTH: 650px; MARGIN-RIGHT: auto"&gt;
&lt;DIV style="FLOAT: left; MARGIN: 10px; TEXT-ALIGN: center"&gt;&lt;A href="http://tomasp.net/articles/aspnet-in-fsharp/openweb.png" target=_blank&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; MARGIN-LEFT: auto; BORDER-LEFT: 0px; MARGIN-RIGHT: auto; BORDER-BOTTOM: 0px" alt="Open Web Site in Visual Studio" src="http://tomasp.net/articles/aspnet-in-fsharp/openweb_sm.png"&gt;&lt;/A&gt;&lt;BR&gt;Figure 1: Open Web Site&lt;/DIV&gt;
&lt;DIV style="FLOAT: left; MARGIN: 10px; TEXT-ALIGN: center"&gt;&lt;IMG alt="Solution Explorer" src="http://tomasp.net/articles/aspnet-in-fsharp/solutionexp.png"&gt;&lt;BR&gt;Figure 2: Solution Explorer&lt;/DIV&gt;
&lt;DIV style="CLEAR: both"&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;As you can see, there are 6 files in the project. The &lt;CODE&gt;Default.aspx.fs&lt;/CODE&gt; and &lt;CODE&gt;Default.aspx&lt;/CODE&gt; together form one web page and the &lt;CODE&gt;DataBinding.aspx.fs&lt;/CODE&gt; with &lt;CODE&gt;DataBinding.aspx&lt;/CODE&gt; form the second web page. The &lt;CODE&gt;App_Code&lt;/CODE&gt; directory contains application logic that can be used from other pages in the project and in our sample project it contains only one file (&lt;CODE&gt;logic.fs&lt;/CODE&gt;). Finally, the &lt;CODE&gt;web.config&lt;/CODE&gt; file contains configuration of the whole application.&lt;/P&gt;
&lt;P&gt;Before we look at the pages you may want to check the &lt;CODE&gt;web.config&lt;/CODE&gt; file, because it needs to contain the correct reference to the CodeDOM provider implementation including a version of the current F# installation. At the time of writing this article, the latest version is &lt;CODE&gt;1.9.3.14&lt;/CODE&gt;, but if you're not sure what version you are using, you can just start the &lt;CODE&gt;fsi.exe&lt;/CODE&gt; from the F# installation which prints the version number. The &lt;CODE&gt;web.config&lt;/CODE&gt; file is an &lt;CODE&gt;xml&lt;/CODE&gt; file and it should contain the following content (with the right version number). The samples in the distribution should contain the correct version number, but the incorrect configuration is a common issue when working with ASP.NET in F#, so it is useful to know what the configuration should look like:&lt;/P&gt;&lt;PRE&gt;&lt;SPAN class=asp&gt;&amp;lt;?&lt;/SPAN&gt;xml version=&lt;SPAN class=str&gt;"1.0"&lt;/SPAN&gt;&lt;SPAN class=asp&gt;?&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;configuration&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;system.web&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;compilation&lt;/SPAN&gt; &lt;SPAN class=attr&gt;debug&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="true"&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;  
  &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;compilers&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;compiler&lt;/SPAN&gt; 
      &lt;SPAN class=attr&gt;language&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="F#;f#;fs;fsharp"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;extension&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;=".fs"&lt;/SPAN&gt; 
      &lt;SPAN class=attr&gt;type&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Microsoft.FSharp.Compiler.CodeDom.FSharpAspNetCodeProvider, 
            FSharp.Compiler.CodeDom, Version=&amp;lt;strong style="&lt;/SPAN&gt;&lt;SPAN class=attr&gt;color:red&lt;/SPAN&gt;;"&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;1.9.3.14&lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;strong&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;, 
            Culture=neutral, PublicKeyToken=a19089b1c74d0809"&lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;
  &lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;compilers&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;compilation&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;system.web&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;configuration&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
&lt;/PRE&gt;
&lt;P&gt;Now, let's look at the &lt;CODE&gt;Default.aspx&lt;/CODE&gt; and &lt;CODE&gt;Default.aspx.fs&lt;/CODE&gt; files that together represent a simple page. The page contains one button and one label (a control that can display some text) and when the user clicks on the button, the result of some calculation is displayed in the label (the calculation is executed on the server-side). The following code is a (slightly simplified) content of the &lt;CODE&gt;Default.aspx&lt;/CODE&gt; file, which defines the HTML markup together with the ASP.NET controls that are on the page:&lt;/P&gt;&lt;PRE&gt;&lt;SPAN class=asp&gt;&amp;lt;%@ Page Language="F#" 
  CodeFile="Default.aspx.fs" Inherits="FSharpWeb.Default" %&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;html&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;body&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;form&lt;/SPAN&gt; &lt;SPAN class=attr&gt;runat&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="server"&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
  &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;asp:Button&lt;/SPAN&gt; 
    &lt;SPAN class=attr&gt;ID&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="btnTest"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;RunAt&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="server"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Text&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Click me!"&lt;/SPAN&gt; 
    &lt;SPAN class=attr&gt;OnClick&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="ButtonClicked"&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;/&amp;gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;br&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;
  &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;asp:Label&lt;/SPAN&gt; &lt;SPAN class=attr&gt;ID&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="lblResult"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;RunAt&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="server"&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;form&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;body&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;html&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
&lt;/PRE&gt;
&lt;P&gt;You can easily identify two server-side controls, because these are written using prefix &lt;CODE&gt;asp&lt;/CODE&gt; and also contain the &lt;CODE&gt;RunAt="server"&lt;/CODE&gt; attribute, which means that the control is processed on the server-side. You can use standard HTML notation for setting attributes of the controls. We set the &lt;CODE&gt;ID&lt;/CODE&gt; attribute to both of the controls, which is important because it allows us to use them in the code-behind code. The &lt;CODE&gt;OnClick&lt;/CODE&gt; attribute of the button sets an event handler - a member of the &lt;CODE&gt;FSharpWeb.Default&lt;/CODE&gt; type from the code-behind file that will be called on the server-side, when a user clicks on the button (which submits the HTML form and causes a page reload, so the event can be processed on the server). The file also contains the first special line, which tells the ASP.NET engine that the page is written in F# and it also tells what source file contains the code-behind code and what is the name of type declared in that file. The code-behind file (&lt;CODE&gt;Default.aspx.fs&lt;/CODE&gt;) has the following content:&lt;/P&gt;&lt;PRE&gt;&lt;SPAN class=preproc&gt;#light&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;namespace&lt;/SPAN&gt; FSharpWeb
&lt;SPAN class=kwrd&gt;open&lt;/SPAN&gt; System
&lt;SPAN class=kwrd&gt;open&lt;/SPAN&gt; System.Web
&lt;SPAN class=kwrd&gt;open&lt;/SPAN&gt; System.Web.UI.WebControls

&lt;SPAN class=kwrd&gt;type&lt;/SPAN&gt; Default() =
  &lt;SPAN class=kwrd&gt;inherit&lt;/SPAN&gt; Page()
  
  &lt;SPAN class=op&gt;[&lt;/SPAN&gt;&amp;lt;DefaultValue&amp;gt;&lt;SPAN class=op&gt;]&lt;/SPAN&gt;
  &lt;SPAN class=kwrd&gt;val&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;mutable&lt;/SPAN&gt; btnTest : Button

  &lt;SPAN class=op&gt;[&lt;/SPAN&gt;&amp;lt;DefaultValue&amp;gt;&lt;SPAN class=op&gt;]&lt;/SPAN&gt;
  &lt;SPAN class=kwrd&gt;val&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;mutable&lt;/SPAN&gt; lblResult : Label

  &lt;SPAN class=kwrd&gt;member&lt;/SPAN&gt; this.ButtonClicked(sender, e) =
    this.lblResult.Text &lt;SPAN class=op&gt;&amp;lt;-&lt;/SPAN&gt; 
      (sprintf &lt;SPAN class=str&gt;"Factorial of 5 is: %d"&lt;/SPAN&gt; 
               (FSharpWeb.Logic.factorial 5))
&lt;/PRE&gt;
&lt;P&gt;As we can see, the file contains an F# object type (named &lt;CODE&gt;Default&lt;/CODE&gt;), inherited from the base ASP.NET &lt;CODE&gt;Page&lt;/CODE&gt; type. Thanks to the recent improvements in F# it is possible to write the type using the new implicit class syntax (note the parentheses after the type name), which means that you can place additional initialization code to the type declaration directly (following the &lt;CODE&gt;inherit&lt;/CODE&gt; clause and F# will treat this as a constructor.&lt;/P&gt;
&lt;P&gt;The class contains a mutable field for every control declared in the declarative markup with the name same as the &lt;CODE&gt;ID&lt;/CODE&gt; attribute in the markup file (&lt;CODE&gt;btnTest&lt;/CODE&gt; and &lt;CODE&gt;lblResult&lt;/CODE&gt;). The ASP.NET initializes these controls automatically when it creates the page (that's why the fields are marked using &lt;CODE&gt;mutable&lt;/CODE&gt;), so we don't need to initialize these fields in our code - F# doesn't usually allow uninitialized fields, but if you place the &lt;CODE&gt;DefaultValue&lt;/CODE&gt; before the field declaration, it will be initialized to the default value (&lt;CODE&gt;null&lt;/CODE&gt;), which is correct, because the field will be later initialized by the ASP.NET runtime. Finally, the type contains a member called &lt;CODE&gt;ButtonClicked&lt;/CODE&gt;, which is a same name we used in the markup for the &lt;CODE&gt;OnClick&lt;/CODE&gt; attribute of the button control. This is an event handler that will be called when user clicks on the button, it performs some calculation (the &lt;CODE&gt;factorial&lt;/CODE&gt; function is declared in the &lt;CODE&gt;logic.fs&lt;/CODE&gt; file) and sets a property of the other control that we have on the page. &lt;/P&gt;
&lt;H2&gt;Personal Web Site in F#&lt;/H2&gt;
&lt;DIV style="FLOAT: right; MARGIN: 10px; TEXT-ALIGN: center"&gt;&lt;A href="http://tomasp.net/articles/aspnet-in-fsharp/pws.png" target=_blank&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; MARGIN-LEFT: auto; BORDER-LEFT: 0px; MARGIN-RIGHT: auto; BORDER-BOTTOM: 0px" alt="Personal Web Site" src="http://tomasp.net/articles/aspnet-in-fsharp/pws_sm.png"&gt;&lt;/A&gt;&lt;BR&gt;Figure 3: Personal Web Site&lt;/DIV&gt;
&lt;P&gt;The second sample ASP.NET project is a port of quite a complex ASP.NET web site which also uses MS SQL database. The database can be created manually as described in &lt;CODE&gt;Welcome.html&lt;/CODE&gt; in the &lt;CODE&gt;PersonalWebSite&lt;/CODE&gt; directory, but I also uploaded the database to my web, so you can just download it and attach it in the SQL server (this is described below and the files for download can be found at the end of the article). The &lt;CODE&gt;PWS_AspNetDb&lt;/CODE&gt; is a database managed by ASP.NET that contains user information - the database below already contains the required role (called &lt;CODE&gt;Administrators&lt;/CODE&gt;) and one user (&lt;CODE&gt;admin&lt;/CODE&gt; with password &lt;CODE&gt;admin123!&lt;/CODE&gt;). The second database file (&lt;CODE&gt;PWS_WebPersonal&lt;/CODE&gt;) contains the application data, mainly information about photos and galleries (as you can see from the screenshot in Figure 3). &lt;/P&gt;
&lt;P&gt;The application uses many advanced ASP.NET features including the following:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Master Pages&lt;/STRONG&gt; - the overall structure of the web site is stored in a master page (&lt;CODE&gt;Default.master&lt;/CODE&gt;) and the other pages use the &lt;CODE&gt;asp:Content&lt;/CODE&gt; control to fill the place holders in the master page.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Site Maps&lt;/STRONG&gt; - the map of the web site is defined in the &lt;CODE&gt;web.sitemap&lt;/CODE&gt; file and is used for generating the menu in the &lt;CODE&gt;Default.master&lt;/CODE&gt; file.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Themes&lt;/STRONG&gt; - the design of the page including CSS files and images are managed using ASP.NET Themes - there are two standard themes in the &lt;CODE&gt;App_Themes&lt;/CODE&gt; directory.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Membership&lt;/STRONG&gt; - the web uses standard ASP.NET technology for managing user accounts including the controls for manipulating with users (e.g. &lt;CODE&gt;asp:CreateUserWizard&lt;/CODE&gt; control is used in &lt;CODE&gt;Register.aspx&lt;/CODE&gt; file).&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Data Controls&lt;/STRONG&gt; - ASP.NET data-access controls are used for reading the data from the application logic layer (implemented as a module in F#)&lt;/LI&gt;&lt;/UL&gt;
&lt;H3&gt;Configuring the databases&lt;/H3&gt;
&lt;P&gt;To configure the databases required by the demo, you can either follow the steps described in the &lt;A href="http://tomasp.net/articles/aspnet-in-fsharp/Welcome.html"&gt;Welcome.html&lt;/A&gt; file (which is part of the sample project), or if you already have some version of SQL Server installed on your machine, you can download the sample databases below (a bunch of MDF and LDF files) and attach them to the SQL Server. I'll explain how to do this using full version of SQL Server, but the steps needed with Express edition are very similar.&lt;/P&gt;
&lt;P&gt;Once you downloaded the files, you'll need to launch SQL Server Management Studio and connect to the server instance. After doing that you should see an "Object Explorer" window, where you can right click on the "Databases" group and select "Attach..." from the pop-up menu. In the opened dialog window, you can add the databases (by selecting the MDF file) and click the "OK" button to attach the databases. Finally, you'll need to modify the &lt;CODE&gt;web.config&lt;/CODE&gt; file in the Personal WebSite sample to include the following section: &lt;/P&gt;&lt;PRE&gt;&lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;connectionStrings&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
 &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;add&lt;/SPAN&gt; &lt;SPAN class=attr&gt;name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Personal"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;providerName&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="System.Data.SqlClient"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;connectionString&lt;/SPAN&gt;=
      &lt;SPAN class=kwrd&gt;"Data Source=.;Integrated Security=True;Database=PWS_WebPersonal"&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;
 &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;remove&lt;/SPAN&gt; &lt;SPAN class=attr&gt;name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="LocalSqlServer"&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;
 &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;add&lt;/SPAN&gt; &lt;SPAN class=attr&gt;name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="LocalSqlServer"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;connectionString&lt;/SPAN&gt;=
      &lt;SPAN class=kwrd&gt;"Data Source=.;Integrated Security=True;Database=PWS_AspNetDb"&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;connectionStrings&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
&lt;/PRE&gt;
&lt;P&gt;The &lt;CODE&gt;Data Source&lt;/CODE&gt; parameter in the connection string specifies the instance of the SQL Server, where the databases are attached. By default this is the name of your computer (which can be written shortly using dot "."). When using the SQL Express the default instance name is ".\SQLExpress". The &lt;CODE&gt;Database&lt;/CODE&gt; parameter specifies the name of the database, which you can see in the "Object Explorer" in the SQL Server Management Studio. After following these steps, you should be able to run the demo application.&lt;/P&gt;
&lt;H3&gt;Data-access in F#&lt;/H3&gt;
&lt;P&gt;Most of the ASP.NET technologies used in the web site are used in almost the same way as in C#, so I will not discuss them in larger details, but the last item in the list - the use of ASP.NET data controls together with F# is I believe quite interesting, so I'll write a few notes about it. Let's look for example at the &lt;CODE&gt;Photos.aspx&lt;/CODE&gt; file, which displays a list of photos in a gallery. The most important parts of the file related to data access are shown in the following code snippet:&lt;/P&gt;&lt;PRE&gt;&lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;asp:DataList&lt;/SPAN&gt; &lt;SPAN class=attr&gt;RunAt&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="server"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;DataSourceID&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="photoSource"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;EnableViewState&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="false"&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;ItemTemplate&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
  &lt;SPAN class=rem&gt;&amp;lt;!-- ... --&amp;gt;&lt;/SPAN&gt;
  &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;a&lt;/SPAN&gt; &lt;SPAN class=attr&gt;href&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;='Details.aspx?AlbumID=&amp;lt;%# base.Eval("PhotoAlbumID") %&amp;gt;'&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;img&lt;/SPAN&gt; &lt;SPAN class=attr&gt;src&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Handler.ashx?PhotoID=&amp;lt;%# base.Eval("&lt;/SPAN&gt;&lt;SPAN class=attr&gt;PhotoID&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;") %&amp;gt;&amp;amp;Size=S"&lt;/SPAN&gt; 
      &lt;SPAN class=attr&gt;class&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="photo_198"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;style&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="border:4px solid white"&lt;/SPAN&gt; 
      &lt;SPAN class=attr&gt;alt&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;='Thumbnail of Photo Number &amp;lt;%# base.Eval("PhotoID") %&amp;gt;'&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;
  &lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;a&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
  &lt;SPAN class=rem&gt;&amp;lt;!-- ... --&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;ItemTemplate&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;asp:DataList&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;

&lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;asp:ObjectDataSource&lt;/SPAN&gt; &lt;SPAN class=attr&gt;ID&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="photoSource"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;RunAt&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="server"&lt;/SPAN&gt; 
  &lt;SPAN class=attr&gt;TypeName&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="PersonalWebSite.PhotoManager"&lt;/SPAN&gt; 
  &lt;SPAN class=attr&gt;SelectMethod&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="GetPhotos"&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
  &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;SelectParameters&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;asp:QueryStringParameter&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="AlbumID"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Type&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Int32"&lt;/SPAN&gt; 
      &lt;SPAN class=attr&gt;QueryStringField&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="albumID"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;DefaultValue&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="0"&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;
  &lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;SelectParameters&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;asp:ObjectDataSource&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
&lt;/PRE&gt;
&lt;P&gt;The first ASP.NET control used in the code is &lt;CODE&gt;asp:DataList&lt;/CODE&gt;, which is a control that simply displays a collection of some items and uses a specified &lt;CODE&gt;ItemTemplate&lt;/CODE&gt; for displaying every single item. In our case we're working with collection of records and the record has several members (including &lt;CODE&gt;PhotoID&lt;/CODE&gt; and &lt;CODE&gt;PhotoAlbumID&lt;/CODE&gt;). To display a value of a record member in the ASP.NET page we have to use ASP.NET &lt;CODE&gt;Eval&lt;/CODE&gt; method as you can see in the sample. The &lt;CODE&gt;Eval&lt;/CODE&gt; method reads the specified member of the item in collection and writing the code in &lt;CODE&gt;&amp;lt;%# ... %&amp;gt;&lt;/CODE&gt; tells ASP.NET that we want to render the result of the expression as a part of the item template. The record that we're using in this example is very simple and has the following structure:&lt;/P&gt;&lt;PRE&gt;&lt;SPAN class=kwrd&gt;type&lt;/SPAN&gt; Photo = 
  { PhotoID:int; 
    PhotoAlbumID:int; 
    PhotoCaption:string; }
&lt;/PRE&gt;
&lt;P&gt;This is actually one of the places where the F# version is shorter, because in C# version you have to write this as a class with properties, which makes the code quite longer.&lt;/P&gt;
&lt;P&gt;The second server-side control (&lt;CODE&gt;asp:ObjectDataSource&lt;/CODE&gt;) in the first code snippet isn't visual, which means that it will not produce any HTML output. It serves just as a declarative data-source for the data list and the properties of this control specify how the content for the data list should be loaded. There are various other data-source controls in ASP.NET (e.g. &lt;CODE&gt;asp:SqlDataSource&lt;/CODE&gt; which loads data directly from the database), but the one that we're using in the example uses a specified .NET/F# type and calls a method of the given object when it needs to retrieve the data. In F# this is even easier, because we can use a name of the module and the code that retrieves the data can be a function in the module.&lt;/P&gt;
&lt;P&gt;As you can see the property &lt;CODE&gt;TypeName&lt;/CODE&gt; is set to &lt;CODE&gt;PersonalWebSite.PhotoManager&lt;/CODE&gt;, which can be treated as a module called &lt;CODE&gt;PhotoManager&lt;/CODE&gt; in a namespace &lt;CODE&gt;PersonalWebSite&lt;/CODE&gt; and the &lt;CODE&gt;SelectMethod&lt;/CODE&gt; property, which specifies a name of the function that will be called when loading the data is set to &lt;CODE&gt;GetPhotos&lt;/CODE&gt;. Finally, the &lt;CODE&gt;SelectParameters&lt;/CODE&gt; specifies that the function expects one argument called &lt;CODE&gt;AlbumID&lt;/CODE&gt; and that the value of this argument should be retrieved from the query string (that is from the URL of form &lt;CODE&gt;photo.aspx?albumIdD=42&lt;/CODE&gt;).&lt;/P&gt;
&lt;P&gt;Now it is pretty easy to implement the module that matches this specifications and can be used as a data source (we could of course use FLinq for loading the data, but I wanted to keep things simple for now, so we're using standard &lt;CODE&gt;SqlDataReader&lt;/CODE&gt; object from .NET):&lt;/P&gt;&lt;PRE&gt;&lt;SPAN class=kwrd&gt;namespace&lt;/SPAN&gt; PersonalWebSite
&lt;SPAN class=rem&gt;// ...&lt;/SPAN&gt;

&lt;SPAN class=kwrd&gt;module&lt;/SPAN&gt; PhotoManager = 
  &lt;SPAN class=rem&gt;// Function will be called by ASP.NET when loading data&lt;/SPAN&gt;
  &lt;SPAN class=rem&gt;// for the asp:DataList control in the 'Photos.aspx' page&lt;/SPAN&gt;
  &lt;SPAN class=kwrd&gt;let&lt;/SPAN&gt; GetPhotos (albumID:int) =
    &lt;SPAN class=rem&gt;// Open connection &amp;amp; create command&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;use&lt;/SPAN&gt; conn = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; SqlConnection(&lt;SPAN class=str&gt;" ... "&lt;/SPAN&gt;)
    &lt;SPAN class=kwrd&gt;use&lt;/SPAN&gt; cmd  = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; SqlCommand(&lt;SPAN class=str&gt;"GetPhotos"&lt;/SPAN&gt;, conn)
    
    &lt;SPAN class=rem&gt;// Can the user see 'private' photos?&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;let&lt;/SPAN&gt; usr = HttpContext.Current.User
    &lt;SPAN class=kwrd&gt;let&lt;/SPAN&gt; filter = not (usr.IsInRole(&lt;SPAN class=str&gt;"Friends"&lt;/SPAN&gt;) &lt;SPAN class=op&gt;|&lt;/SPAN&gt;&lt;SPAN class=op&gt;|&lt;/SPAN&gt; usr.IsInRole(&lt;SPAN class=str&gt;"Administrators"&lt;/SPAN&gt;))
    cmd.CommandType &lt;SPAN class=op&gt;&amp;lt;-&lt;/SPAN&gt; CommandType.StoredProcedure)
    cmd.Parameters.Add(SqlParameter(&lt;SPAN class=str&gt;"@AlbumID"&lt;/SPAN&gt;, albumID)) &lt;SPAN class=op&gt;|&lt;/SPAN&gt;&amp;gt; ignore
    command.Parameters.Add(SqlParameter(&lt;SPAN class=str&gt;"@IsPublic"&lt;/SPAN&gt;, filter)) &lt;SPAN class=op&gt;|&lt;/SPAN&gt;&amp;gt; ignore
    conn.Open()
    
    &lt;SPAN class=rem&gt;// Read all photos into a .NET ResizeArray type&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;let&lt;/SPAN&gt; list = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; ResizeArray&amp;lt;&lt;SPAN class=op&gt;_&lt;/SPAN&gt;&amp;gt;()
    &lt;SPAN class=kwrd&gt;use&lt;/SPAN&gt; reader = command.ExecuteReader()
    &lt;SPAN class=kwrd&gt;while&lt;/SPAN&gt; (reader.Read()) &lt;SPAN class=kwrd&gt;do&lt;/SPAN&gt;
      list.Add({ PhotoID = unbox (reader.get_Item(&lt;SPAN class=str&gt;"PhotoID"&lt;/SPAN&gt;)) 
                 PhotoAlbumID = unbox (reader.get_Item(&lt;SPAN class=str&gt;"AlbumID"&lt;/SPAN&gt;)) 
                 PhotoCaption = unbox (reader.get_Item(&lt;SPAN class=str&gt;"Caption"&lt;/SPAN&gt;)) }) 
                 
    &lt;SPAN class=rem&gt;// Return the created collection&lt;/SPAN&gt;
    list 
&lt;/PRE&gt;
&lt;P&gt;I hope this article explained some of the interesting things that you may find in the ASP.NET samples provided with the F# distribution and I think that the Personal WebSite Sample shows that F# can be used for writing quite complicated web applications as well. Of course, my initial motivation for writing web applications in F# is the possibility of using meta-programming to develop client-side code (the code that runs on the client as a JavaScript) in F# too, which makes development of modern "Ajax"-style applications easier, so if you're interested in this project you may want to look at F# Web Tools [&lt;A&gt;1&lt;/A&gt;].&lt;/P&gt;
&lt;H2&gt;Downloads &amp;amp; References &lt;A name=myfsstuff&gt;&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://tomasp.net/articles/aspnet-in-fsharp/databases.zip"&gt;Download PWS Database Files&lt;/A&gt; (9.65 MB)&lt;/LI&gt;&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;[1] &lt;A href="http://tomasp.net/blog/fswebtools-intro.aspx"&gt;F# Web Toolkit: "Ajax" applications made simple&lt;/A&gt; [&lt;A href="http://tomasp.net/blog/fswebtools-intro.aspx" target=_blank&gt;^&lt;/A&gt;] - Blog | TomasP.Net&lt;/LI&gt;
&lt;LI&gt;[2] &lt;A href="http://msdn2.microsoft.com/en-us/express/aa700818.aspx#personal"&gt;Visual Web Developer Express: Samples and Starter Kits&lt;/A&gt; [&lt;A href="http://msdn2.microsoft.com/en-us/express/aa700818.aspx#personal" target=_blank&gt;^&lt;/A&gt;] - Microsoft.Com&lt;/LI&gt;&lt;/UL&gt;&lt;/DIV&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=5244" width="1" height="1"&gt;</description></item><item><title>Using computation expressions to control monitor locks</title><link>http://cs.hubfs.net/blogs/hell_is_other_languages/archive/2008/02/17/4892.aspx</link><pubDate>Sun, 17 Feb 2008 13:40:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:4892</guid><dc:creator>gneverov</dc:creator><slash:comments>6</slash:comments><description>&lt;P&gt;Using computation expressions to control monitor locks&lt;/P&gt;
&lt;P&gt;C# has the lock statement to support the use of .NET monitor synchronization. &lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;lock&lt;/span&gt;(&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;this&lt;/span&gt;) { x--; }&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;This curly-brace delimited block of atomic statements is easily identified in code. However having to call Wait or Pulse inside the block is less appealing because this previously hidden &lt;A href="http://msdn2.microsoft.com/en-us/library/system.threading.monitor.aspx"&gt;Monitor&lt;/A&gt; class now comes to your attention and you have to make sure you wait/pulse on the same object that was locked.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;lock&lt;/span&gt;(&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;this&lt;/span&gt;) { x--; &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt;(x==0) Monitor.Pulse(&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;this&lt;/span&gt;); }&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;F# has the lock function which is basically a higher-order function version of C#'s lock statement. It has the same un-niceness with wait/pulse, plus you have to construct the body of the block into a function, and to me braces &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;{…}&lt;/span&gt; look better than the verbose &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;(&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; () -&amp;gt; …)&lt;/span&gt;.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;lock this (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; () -&amp;gt; decr x; &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; x=0 &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;then&lt;/span&gt; Monitor.Pulse(this))&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;We can solve all these issues and more with computation expressions in F#. We start by defining the Lock monad, which is actually just an instance of the &lt;A href="http://www.haskell.org/all_about_monads/html/readermonad.html"&gt;reader monad&lt;/A&gt;. A value of type &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;Lock&amp;lt;'a&amp;gt;&lt;/span&gt; is a computation that will execute under the context of a lock and return a result of type &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;'a&lt;/span&gt;. The type of the Lock monad is a function that accepts the locked object and returns the result of the computation. The following return and bind functions are the standard implementation of the reader monad.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;type&lt;/span&gt; Lock&amp;lt;'a&amp;gt; = Lock of (obj -&amp;gt; 'a)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; apply (Lock f) lock = f lock&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; mreturn x = Lock (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; lock -&amp;gt; x)&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; bind m f = Lock (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; lock -&amp;gt; apply (f (apply m lock)) lock)&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Next we need a function to run a Lock computation. This function takes as arguments an object to lock and the computation to run. It acquires a lock on the object, runs the computation and then releases the lock.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;(* val run : 'a -&amp;gt; Lock&amp;lt;'b&amp;gt; -&amp;gt; 'b *)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; run lock m =&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; lock = &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;box&lt;/span&gt; lock&lt;br /&gt;  Monitor.Enter(lock)&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;try&lt;/span&gt; apply m lock&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;finally&lt;/span&gt; Monitor.Exit(lock)&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Next we'll define some monadic actions for wait and pulse.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;(* val wait : Lock&amp;lt;unit&amp;gt; *)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; wait = Lock (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; lock -&amp;gt; Monitor.Wait(lock) |&amp;gt; ignore)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;(* val tryWait : int -&amp;gt; Lock&amp;lt;bool&amp;gt; *)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; tryWait (timeout : &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;) = Lock (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; lock -&amp;gt; Monitor.Wait(lock, timeout))&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;(* val pulse : Lock&amp;lt;unit&amp;gt; *)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; pulse = Lock (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; lock -&amp;gt; Monitor.Pulse(lock))&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;(* val pulseAll : Lock&amp;lt;unit&amp;gt; *)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; pulseAll = Lock (&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;fun&lt;/span&gt; lock -&amp;gt; Monitor.PulseAll(lock))&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Finally we need a builder class to enable computation expression syntax on the Lock type. This code is omitted here but can be downloaded in the &lt;A href="/blogs/hell_is_other_languages/attachment/4565.ashx"&gt;full example&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Now at last we can write lock code in F# with curly braces, without seeing the Monitor class, and without reproducing the locked object to call wait and pulse.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;lock { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt; decr x&lt;br /&gt;       &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; x = 0 &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;then&lt;/span&gt; return! pulse } |&amp;gt; run this&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Or a more complex example&lt;BR&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;lock { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;while&lt;/span&gt; ready.Count = 0 &amp;amp;&amp;amp; !pending &amp;gt; 0 &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt; return! wait&lt;br /&gt;       &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; ready.Count &amp;gt; 0 &lt;br /&gt;       &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;then&lt;/span&gt; return Some (ready.Dequeue())&lt;br /&gt;       &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;else&lt;/span&gt; return None } |&amp;gt; run myLock&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;You can even have an alternate run function that takes a timeout on acquiring the lock.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;(* val tryRun : 'a -&amp;gt; int -&amp;gt; Lock&amp;lt;'b&amp;gt; -&amp;gt; 'b option *)&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; tryRun lock (timeout : &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;) m =&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; lock = &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;box&lt;/span&gt; lock&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; Monitor.TryEnter(lock, timeout)&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;then&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;try&lt;/span&gt; Some (apply m lock)&lt;br /&gt;         &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;finally&lt;/span&gt; Monitor.Exit(lock)&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;else&lt;/span&gt; None&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Additionally the Lock monad can be used to make synchronized code more composable. Say you have method that always needs to execute under a lock but either you don't know which lock or the lock needs to be entered at an outer scope. You can write this method so that it returns a Lock computation, which can be composed with other Lock computations. Consider functions to synchronously access items in a System.Collections.Generic.&lt;A href="http://msdn2.microsoft.com/en-us/library/7977ey2c.aspx"&gt;Queue&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;(* val enqueue : Queue&amp;lt;’a&amp;gt; -&amp;gt; ‘a -&amp;gt; Lock&amp;lt;unit&amp;gt; *)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; enqueue (q : Queue&amp;lt;_&amp;gt;) x = &lt;br /&gt;  lock { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;if&lt;/span&gt; q.Count = 0 &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;then&lt;/span&gt; return! pulseAll&lt;br /&gt;         &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt; q.Enqueue(x) }&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;(* val dequeue : Queue&amp;lt;’a&amp;gt; -&amp;gt; Lock&amp;lt;’a&amp;gt; *)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; dequeue (q : Queue&amp;lt;_&amp;gt;) = &lt;br /&gt;  lock { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;while&lt;/span&gt; q.Count = 0 &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt; return! wait&lt;br /&gt;         return q.Dequeue() }&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Because these functions return a &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;Lock&amp;lt;_&amp;gt;&lt;/span&gt; value the caller can never forget to acquire the lock and this will be enforced by the type system (of course the programmer can still acquire the &lt;EM&gt;wrong&lt;/EM&gt; lock). Secondly these functions can naturally call pulse and wait without knowing the object the lock is acquired on. &lt;/P&gt;
&lt;P&gt;With these functions you can easily write code that atomically moves an item between queues and returns the item.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; move q1 q2 = &lt;br /&gt;  lock { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! x = dequeue q1 &lt;br /&gt;         &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt;! enqueue q2 x&lt;br /&gt;         return x } |&amp;gt; run myLock&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;So if you &lt;EM&gt;have&lt;/EM&gt; to use locks because you don't like &lt;A href="/blogs/hell_is_other_languages/archive/2008/01/16/4565.aspx"&gt;STM&lt;/A&gt; or its performance isn't good enough or for legacy reasons, the lock monad could improve readability and abstraction.&lt;BR&gt;&lt;/P&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=4892" width="1" height="1"&gt;</description><enclosure url="http://cs.hubfs.net/blogs/hell_is_other_languages/attachment/4892.ashx" length="878" type="application/x-zip-compressed" /></item><item><title>Software Transactional Memory for F#</title><link>http://cs.hubfs.net/blogs/hell_is_other_languages/archive/2008/01/16/4565.aspx</link><pubDate>Tue, 15 Jan 2008 14:11:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:4565</guid><dc:creator>gneverov</dc:creator><slash:comments>18</slash:comments><description>&lt;P&gt;I have written a library for using software transactional memory in F#. The library exposes memory transactions as a monad using F#’s new &lt;A href="http://blogs.msdn.com/dsyme/archive/2007/09/22/some-details-on-f-computation-expressions-aka-monadic-or-workflow-syntax.aspx"&gt;computation expression&lt;/A&gt; feature. It can be downloaded &lt;A href="/blogs/hell_is_other_languages/attachment/4565.ashx"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Software transactional memory (STM) is an approach to concurrent programming that avoids the use of traditional, error-prone locks to control access to shared memory. Instead of using locks a programmer specifies sections of code that will make atomic changes to shared memory. &lt;/P&gt;
&lt;P&gt;The design and implementation of this F# library is blatantly copied from the paper &lt;A href="http://research.microsoft.com/~simonpj/papers/stm/index.htm#composble"&gt;Composable Memory Transactions&lt;/A&gt;. I am enormously grateful to the authors of this paper whose clear and precise explanation made the implementation of this complicated piece of software almost trivial.&lt;/P&gt;
&lt;P&gt;The low-level STM machinery is implemented in the file stm.cs. It is written in C# mainly because I was working off existing code I’d written some time ago, but there’s no reason why it could not be written in F#. It is all managed code and internally uses monitors for synchronization. It currently uses a very coarse grained lock meaning that only one transaction can commit at once and every waiting thread is resumed when a transaction completes, but this can be improved with more work. The implementation follows the description in the paper.&lt;/P&gt;
&lt;P&gt;The F# monadic interface is in the file stm.fs. It imports definitions from the C# assembly and defines the monad type &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;Stm&amp;lt;'a&amp;gt;&lt;/span&gt; with corresponding builder class to enable computation expression syntax. An issue with the implementation of STM systems is how to access the transaction log to make reads and writes during a transaction. Two common approachs are to use thread-local storage which is slow, or implicitly pass the transaction log as an extra parameter to every function, which requires code generation. The advantage of using computation expressions (or monadic do notation) is that the transaction log is explicitly passed between functions by the programmer’s code, thereby avoiding compiler modification, but also avoiding the need for the programmer to manually manage the transaction log parameter passing scheme&amp;nbsp;as well.&lt;/P&gt;
&lt;P&gt;With these two layers in place one can write STM code in F#. Transacted memory locations have the type &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;TVar&amp;lt;'a&amp;gt;&lt;/span&gt;. This is a reference cell like &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;Ref&amp;lt;'a&amp;gt;&lt;/span&gt; in F# but its value can only be read and written from inside a transaction. A TVar is created using the &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;newTVar&lt;/span&gt; function.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; x = newTVar 0&lt;/span&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; x : TVar&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This code is similar to &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; x = ref 0&lt;/span&gt;, but being a TVar instead of a Ref, the location &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;x&lt;/span&gt; can be safely shared between multiple threads. &lt;/P&gt;
&lt;P&gt;A transaction is defined using a computation expression. A transaction is a value of type &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;Stm&amp;lt;'a&amp;gt;&lt;/span&gt; which represents a computation that when executed will make an atomic change to the values of zero or more TVars and then return a value of type &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;'a&lt;/span&gt;. The type system ensures at compile-time that all reads and writes to a TVar only take place inside a transaction. The functions &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;readTVar&lt;/span&gt; and &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;writeTVar&lt;/span&gt; read and write a TVar respectively. They are analogous to &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; v = !x&lt;/span&gt; and &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;x &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;:=&lt;/span&gt; v&lt;/span&gt; for regular reference cells.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; readTVar : TVar&amp;lt;'a&amp;gt; -&amp;gt; Stm&amp;lt;'a&amp;gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; writeTVar : TVar&amp;lt;'a&amp;gt; -&amp;gt; 'a -&amp;gt; Stm&amp;lt;unit&amp;gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Let’s define a function that increments the value stored in a TVar.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; incr x = &lt;br /&gt;  stm {&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! v = readTVar x&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt;! writeTVar x (v+1)&lt;br /&gt;    return v }&lt;/span&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; incr : TVar&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt; -&amp;gt; Stm&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The syntax &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;stm { … }&lt;/span&gt; is an F# computation expression using the 'stm' monad, which means that this is a memory transaction (as opposed to an &lt;A href="http://blogs.msdn.com/dsyme/archive/2007/10/11/introducing-f-asynchronous-workflows.aspx"&gt;async work unit&lt;/A&gt; or something). The value of the location is read and stored in &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;v&lt;/span&gt;. The incremented value is then written back to the location and &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;v&lt;/span&gt; is returned as the result of the computation. When executed the read and write happen as an atomic block which means logically that an interleaving thread won’t access the location between the read and write.&lt;/P&gt;
&lt;P&gt;A transaction is executed by the &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;atomically&lt;/span&gt; function. &lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; : atomically : Stm&amp;lt;'a&amp;gt; -&amp;gt; 'a&lt;/span&gt;&lt;/P&gt;
&lt;P dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;incr x |&amp;gt; atomically&lt;/span&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; it : &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt; = 0&lt;/span&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;incr x |&amp;gt; atomically&lt;/span&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; it : &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt; = 1&lt;/span&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The composability of STM can be seen by the ability to compose &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;incr&lt;/span&gt; into a larger transaction that increments a location twice.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; incr2 x =&lt;br /&gt;  stm { &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! _ = incr x&lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! v = incr x&lt;br /&gt;    return v }&lt;/span&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; incr2 : TVar&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt; -&amp;gt; Stm&amp;lt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;incr2 x |&amp;gt; atomically&lt;/span&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; it : &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;int&lt;/span&gt; = 3&lt;/span&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Imagine that &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;incr&lt;/span&gt; was part of the public interface of a module. If &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;incr&lt;/span&gt; used a lock to perform the read and write atomically then it would be impossible for users of the library to write &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;incr2&lt;/span&gt; unless the module also exposed its locks through a public interface, which would make programming intricate for the user.&lt;/P&gt;
&lt;P&gt;If you see any Haskell STM code, it is straightforward to translate this into F#. For example the paper gives the implementation of an MVar as a code example. The paper describes an MVar as&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;EM&gt;An MVar is a mutable location like a TVar, except that it may be either empty, or full with a value. The takeMVar function leaves a full MVar empty, and blocks on an empty MVar. A putMVar on an empty MVar leaves it full, and blocks on a full MVar. So MVars are, in effect, a one-place channel.&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;MVars can be implemented in F# STM like so.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;type&lt;/span&gt; MVar&amp;lt;'a&amp;gt; = TVar&amp;lt;option&amp;lt;'a&amp;gt; &amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; newEmptyMVar () = newTVar None&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; newFullMVar v = newTVar (Some v)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; takeMVar mv = &lt;br /&gt;  stm { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! v = readTVar mv&lt;br /&gt;        return! &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;match&lt;/span&gt; v &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;with&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Some a -&amp;gt; &lt;br /&gt;                    stm { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;do&lt;/span&gt;! writeTVar mv None&lt;br /&gt;                          return a }&lt;br /&gt;                &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; None -&amp;gt; retry () }&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; putMVar mv a =&lt;br /&gt;  stm { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! v = readTVar mv&lt;br /&gt;        return! &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;match&lt;/span&gt; v &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;with&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; None -&amp;gt; writeTVar mv (Some a)&lt;br /&gt;                &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;|&lt;/span&gt; Some _ -&amp;gt; retry () }&lt;/span&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; newEmptyMVar : unit -&amp;gt; MVar&amp;lt;'a&amp;gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; newFullMVar : 'a -&amp;gt; MVar&amp;lt;'a&amp;gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; takeMVar : MVar&amp;lt;'a&amp;gt; -&amp;gt; Stm&amp;lt;'a&amp;gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; putMVar : MVar&amp;lt;'a&amp;gt; -&amp;gt; 'a -&amp;gt; Stm&amp;lt;unit&amp;gt;&lt;/span&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;retry&lt;/span&gt; operation is used to re-execute a transaction from the beginning. There is no point re-executing the transaction immediately because no memory locations will have changed. So the retry operation blocks until some memory changes that might allow the transaction to make further progress. This is how blocking is implemented with STM.&lt;/P&gt;
&lt;P&gt;Another feature of STM that makes it more composable than locks is how it handles blocking. The get/put MVar operations above are blocking operations. If an MVar library was written using locks and non-blocking versions of these operations were required then they would have to be implemented by the library developer and exposed as part of the library’s public interface. Not so with STM: if the MVar interface only exposes blocking get/put operations then it is possible for the user of the library to write the non-blocking versions, and vice-versa.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; tryTakeMVar mv = &lt;br /&gt;  orElse &lt;br /&gt;    (stm { &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt;! v = takeMVar mv&lt;br /&gt;           return Some v })&lt;br /&gt;    (stm { return None })&lt;/span&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;val&lt;/span&gt; tryTakeMVar mv : MVar&amp;lt;'a&amp;gt; -&amp;gt; Stm&amp;lt;'a option&amp;gt;&lt;/span&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The function &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;tryTakeMVar&lt;/span&gt; is the non-blocking version of &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;takeMVar&lt;/span&gt;; it returns an option value depending on whether a value was available. The key here is the &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;orElse&lt;/span&gt; operation. This function takes two transactions and tries to execute the first. If the first fails with a retry/block then it executes the second. So in this example if &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;takeMVar&lt;/span&gt; retries/blocks then it will return &lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;None&lt;/span&gt;.&lt;/P&gt;
&lt;P&gt;Also included in the code download is the &lt;A href="http://research.microsoft.com/~simonpj/papers/stm/index.htm#beautiful"&gt;Santa program&lt;/A&gt;, a singly-linked list queue, and a fixed-length array queue.&lt;/P&gt;
&lt;P&gt;Of course all these great benefits of STM come at a price, and that price is performance. An STM program is probably always going to be slower than a lock-based program. This STM implementation was engineered for correctness and design of the monadic interface and so probably has really bad performance.&lt;BR&gt;&lt;/P&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=4565" width="1" height="1"&gt;</description><enclosure url="http://cs.hubfs.net/blogs/hell_is_other_languages/attachment/4565.ashx" length="9791" type="application/x-zip-compressed" /></item><item><title>Some notes about using F# in ProjectEuler</title><link>http://cs.hubfs.net/blogs/solong/archive/2008/01/14/4561.aspx</link><pubDate>Tue, 15 Jan 2008 05:20:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:4561</guid><dc:creator>LewisBruck</dc:creator><slash:comments>4</slash:comments><description>&lt;P&gt;(After a long hiatus of just lurking and posting to the forums, I am trying to start blogging again.)&lt;/P&gt;
&lt;P&gt;Like many people, I recently discovered &lt;A href="http://projecteuler.net/"&gt;http://projecteuler.net&lt;/A&gt;.&amp;nbsp; The site contains a set of mathematically oriented programming problems that get progressively harder.&amp;nbsp; I started solving them using F#.&amp;nbsp; While doing so, I've come up with some comments on how F# is really good for these kinds of problems and some improvements that would be nice and probably applicable to more general kinds of programs.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;BigInt rules!&amp;nbsp; Since a lot of the problems are calculations on large integers, it is nice to have them available.&amp;nbsp; It would be nice if there was a "bigint" equivalent to the "int" and "float" functions to simplify conversions.&amp;nbsp; It would be really nice if there was a way to override the default numeric behavior of assuming that every number is an int;&amp;nbsp; it would be nice to be able to switch to "float" or "bigint" mode and have the type checker make the appropriate assumptions. 
&lt;LI&gt;A minor nit, but it would be nice to have a predefined identity function.&amp;nbsp; I seem to have one in each program I write (even beyond ProjectEuler). 
&lt;LI&gt;For most of the problems, I'd&amp;nbsp;create a sequence expression with individual calculations and then aggregate the desired result after filtering.&amp;nbsp; This demonstrated the convenience of sequence comprehensions, but we already knew that :-) 
&lt;LI&gt;I tried to avoid "normal" imperative for and while loops and created new helper functions to work on sequences:&amp;nbsp; seqUntil and seqWhile would process a sequence depending on a boolean function, seqAll would see if a function was true for all values in a sequence (the counterpart to Seq.exists), seqSkip would remove the first n entries in a sequence (really creative name, there :-),&amp;nbsp; etc.&amp;nbsp; I think that a lot of these functions, especially the ones that are in the Haskell Prelude for lists, would be good additions to the Seq module. 
&lt;LI&gt;It would be nice to have&amp;nbsp;some of the&amp;nbsp;aggregation operations be representable in the comprehension language.&amp;nbsp; This has been described Simon Peyton-Jones and Phil Wadler in &lt;A href="http://research.microsoft.com/Users/simonpj/papers/list-comp/index.htm"&gt;Comprehensive Comprehensions&lt;/A&gt;&amp;nbsp;for Haskell and should be&amp;nbsp;applicable to F# as well. 
&lt;LI&gt;I've noticed that I mix the sequence comprehension syntax with the "old-style" pipeline syntax a lot, even when the function could be done in a sequence comprehension.&amp;nbsp; Looking back, it seems that if I am exploring (ok, guessing) a solution incrementally, it is easier to do that by adding new Seq.map, Seq.filter, or Seq.fold functions at the end with "|&amp;gt;" while running each step in fsi.&amp;nbsp;&amp;nbsp;Would it help&amp;nbsp;if there was a way to run and augment&amp;nbsp;sequence comprehensions incrementally in fsi?&amp;nbsp; If I knew the path to the solution(or subsolution), I would choose to use the comprehension syntax first. 
&lt;LI&gt;While there seems to have been an interest in having F# be an alternative to Matlab for some kinds of engineering computing, I think that it could give Mathematica a run for its money in the computational and presentation space.&amp;nbsp; Adding full symbolic math support would be nice, but a harder challenge...&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;It has been a fun diversion to work on these problems, and interesting to see how concise the F# solutions are compared to the other languages represented.&amp;nbsp; The solutions in &lt;A href="http://www.jsoftware.com"&gt;J&lt;/A&gt; are always the smallest, but I haven't grokked the syntax to understand the solutions yet :-)&amp;nbsp; The assembly language solutions are always interesting to read, but it is nice to see F# solutions that are as concise as the Ruby and Python solutions but running much faster...&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=4561" width="1" height="1"&gt;</description></item><item><title>F# 1.9.3 Release Candidate (1.9.3.7) is now available</title><link>http://cs.hubfs.net/blogs/thepopeofthehub/archive/2007/12/01/FSharp1_9_3Released.aspx</link><pubDate>Sun, 02 Dec 2007 05:18:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:4216</guid><dc:creator>optionsScalper</dc:creator><slash:comments>2</slash:comments><description>&lt;P&gt;Dr. Don Syme and the F# team have provided a "stabilization" release of F#.&amp;nbsp; It looks like they are starting a "cleanup" in preparation of becoming a product.&amp;nbsp; Woo Hoo!&lt;/P&gt;
&lt;P&gt;Dr. Syme's full post is &lt;A href="http://blogs.msdn.com/dsyme/archive/2007/11/30/f-1-9-3-candidate-release-now-available.aspx"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;The release notes are &lt;A href="http://blogs.msdn.com/dsyme/archive/2007/11/30/full-release-notes-for-f-1-9-3-7.aspx"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Download it as an &lt;A href="http://research.microsoft.com/research/downloads/Details/e8478d6b-49c0-4750-80eb-0e424d1631a3/Details.aspx"&gt;MSI&lt;/A&gt; or &lt;A href="http://research.microsoft.com/research/downloads/Details/eec29583-ecff-42c3-a2ee-c1502145dc90/Details.aspx"&gt;ZIP&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=4216" width="1" height="1"&gt;</description></item><item><title>Using F# with R</title><link>http://cs.hubfs.net/blogs/thepopeofthehub/archive/2007/11/06/FSharpWithR.aspx</link><pubDate>Tue, 06 Nov 2007 08:02:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:3945</guid><dc:creator>optionsScalper</dc:creator><slash:comments>5</slash:comments><description>&lt;P&gt;On the F# list server over at Microsoft Research, there was a question posted by Lars Johnson about using F# with R.&amp;nbsp; For whatever reason, I'm not able to post to that list server.&amp;nbsp; I'm not very good with list servers, so I'll post up my usage here and hope that someone could post this back to the list server or notify Lars.&lt;/P&gt;
&lt;P&gt;For those that don't know, R is an analytics tool with an emphasis on rich statistical toolboxes.&amp;nbsp; It was first produced at the old AT&amp;amp;T Bell Labs and was later commercialized by Stat-Sci (later to become Insightful) as S-Plus.&amp;nbsp; R remains free and in the public domain.&lt;/P&gt;
&lt;P&gt;In the list server thread, Juergen Van Gael mentioned two approaches for possible integration - RSOAP and R(D)COM.&amp;nbsp; This post is for usage of R with R(D)COM with F#.&amp;nbsp; The RSOAP approach is a little more involved, so I chose the R(D)COM path here.&amp;nbsp; As its name implies, R(D)COM is a wrapper for R for usage with COM and DCOM.&amp;nbsp; It was written by Thomas Baier and Erich Neuwirth.&lt;/P&gt;
&lt;P&gt;My environment for use of F# with R on a Windows platform:&lt;/P&gt;
&lt;P&gt;1.&amp;nbsp; Windows XP SP2&lt;BR&gt;2.&amp;nbsp; .NET 2.0 - 2.0.50727&lt;BR&gt;3.&amp;nbsp; Visual Studio 2005 with SP1 - 8.0.50727.762 (SP.050727-7600)&lt;BR&gt;4.&amp;nbsp; F# 1.9.2.9&lt;BR&gt;5.&amp;nbsp; R 2.6.0 - &lt;A href="http://cran.us.r-project.org/"&gt;http://cran.us.r-project.org/&lt;/A&gt;&lt;BR&gt;6.&amp;nbsp; R(D)COM 2.50_pl1 - &lt;A href="http://rcom.univie.ac.at/"&gt;http://rcom.univie.ac.at/&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Note that VS2005 is not necessary as this could be done with the .NET Framework and F#.&lt;/P&gt;
&lt;P&gt;After the above installation, we need to make an R(D)COM .NET wrapper so that F# or any .NET application can see the R(D)COM server.&amp;nbsp; For this, I opened a VS2005 command prompt (dos window with the VS2005 environment variables properly set up).&amp;nbsp; In that window, perform the following two steps.&amp;nbsp; After you complete these steps, the command window is no longer needed.&lt;/P&gt;
&lt;P&gt;1.&amp;nbsp; Change directory to the default installation for the R(D)COM binaries.&amp;nbsp; "cd C:\Program Files\R\(D)COM Server\bin".&lt;BR&gt;2.&amp;nbsp; Create the .NET interop wrapper.&amp;nbsp; "TlbImp STATCONNECTORSRV.exe /out:Interop.STATCONNECTORSRVLib.dll".&amp;nbsp; Note that while this is a standard operation for .NET with COM, Robert Pickering's book "Foundations of F#" covers COM usage with F# (and other interoperability) in Chapter 13.&lt;/P&gt;
&lt;P&gt;Next, open up a copy of fsi and interact with the following code.&lt;/P&gt;
&lt;P&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt; &lt;br /&gt;&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;//-----------------------------&lt;/span&gt;&lt;br /&gt;#light&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;// attach a copy of the R(D)COM dll for statistics connections.&lt;/span&gt;&lt;br /&gt;#r &lt;span style="color: Red;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;@"C:\Program Files\R\(D)COM Server\bin\Interop.STATCONNECTORSRVLib.dll"&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;// open the namespace&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;open&lt;/span&gt; Interop.STATCONNECTORSRVLib&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;// Create a connection instance&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; SCCForR = &lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;new&lt;/span&gt; StatConnectorClass()&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;// Initialize that instance for usage with R&lt;/span&gt;&lt;br /&gt;SCCForR.Init(&lt;span style="color: Red;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;"R"&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;// Sample statements to modify the R environment.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;// create an R variable named abc and assign it the value of 5&lt;/span&gt;&lt;br /&gt;SCCForR.SetSymbol(&lt;span style="color: Red;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;"abc"&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;,&lt;/span&gt; 5)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;// Retrieve the value of the R variable named abc and assign that value to the F# value valueForabc&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; valueForabc = SCCForR.GetSymbol(&lt;span style="color: Red;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;"abc"&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;// Evaluate an expression in R and assign that value to an F# value aTestEvaluation&lt;/span&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;let&lt;/span&gt; aTestEvaluation = SCCForR.Evaluate(&lt;span style="color: Red;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;"8 * sin(4)"&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;// Close the R connection&lt;/span&gt;&lt;br /&gt;SCCForR.Close()&lt;br /&gt;&lt;span style="color: Green;background-color: Transparent;font-family: Lucida Console;font-size: 11px;font-weight: normal;"&gt;//-----------------------------&lt;/span&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Note that the value for valueForabc should be 5.&amp;nbsp; The value for aTestEvaluation should be -6.054419962.&amp;nbsp; Also note that this sample does NOT clean up the COM object assigned to SCCForR.&amp;nbsp; It only closes the connection to R.&lt;/P&gt;
&lt;P&gt;This sample interop code was modified from the example given in the R(D)COM package.&amp;nbsp; There are many other possibilities for R(D)COM, especially in the rich graphics libraries that R has to offer.&lt;BR&gt;&lt;/P&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=3945" width="1" height="1"&gt;</description></item><item><title>F# Overview - Introduction to the F# language</title><link>http://cs.hubfs.net/blogs/tomasp/archive/2007/11/03/fsharp_introduction.aspx</link><pubDate>Sat, 03 Nov 2007 01:36:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:3924</guid><dc:creator>tomasp</dc:creator><slash:comments>7</slash:comments><description>&lt;P&gt;In my bachelor thesis I included a short introduction that covered all of the important aspects of the F# programming language and I thought that it may be useful to extend it a little bit to cover also a topics that were not important for my thesis and post it as an article, so there is one and relatively short article that introduces all the interesting F# features. The article got however a bit longer than I expected, so I decided to split it into a three parts that would introduce three different &lt;EM&gt;paradigms&lt;/EM&gt; that are supported by F#. Of course, this series won’t teach you everything about F#, but it tries to cover the main F# design goals and (hopefully) presents all the features that make F# interesting and worth learning. In this first part I will shortly introduce F# and the supported paradigms that will be discussed in the upcoming articles.&lt;/P&gt;
&lt;H2&gt;Introducing F#&lt;/H2&gt;
&lt;P&gt;In one of the papers about F#, the F# designers gave the following description: &lt;EM&gt;"F# is a multi-paradigm .NET language explicitly designed to be an ML suited to the .NET environment. It is rooted in the Core ML design and in particular has a core language largely compatible with OCaml"&lt;/EM&gt;. In other words this means that the syntax of the F# language is similar to ML or OCaml (don’t worry if you don’t know these languages, we’ll look at some examples shortly), but the F# language targets .NET Framework, which means that it can natively work with other .NET components and also that it contains several language extensions to allow smooth integration with the .NET object system. &lt;/P&gt;
&lt;P&gt;Another important aspect mentioned in this description is that F# is &lt;EM&gt;multi-paradigm&lt;/EM&gt; language. This means that it tries to take the best from many programming languages from very different worlds. The first paradigm is &lt;EM&gt;functional programming&lt;/EM&gt; (the languages that largely influenced the design of F# in this area are ML, OCaml and other), which has a very long tradition and is becoming more important lately for some very appealing properties, including the fact that functional code tends to be easier to test and paralellize and is also extensible in a ways where object oriented code makes extending difficult. &lt;/P&gt;
&lt;P&gt;The second paradigm is widely adopted &lt;EM&gt;object oriented&lt;/EM&gt; programming, which enables interoperability with other .NET languages. In F# it is often used for implementing elementary data types (meaning that the operations on the type are well known and change very rarely), for grouping a set of elementary functions that are together used to perform some complicated operation (i.e. implementing an interface) and also when working with object oriented user interface frameworks. &lt;/P&gt;
&lt;P&gt;Finally, the third paradigm supported by F# is &lt;EM&gt;language oriented programming&lt;/EM&gt; (the design of F# in this area is largely influenced by ML, Haskell and also by LINQ). In general, language oriented programming is focused on developing executors for some code which has a structure of a language (be it a declarative language like XML, or a fully powerful language like some subset of F#). In this overview, I will focus on two techniques provided by F# that allow you to give a different meaning to a blocks of F# code. In a programming language theory, this is often called &lt;EM&gt;internal domain specific languages&lt;/EM&gt;, because the code is written in the host language, but is specifically designed as a way for solving problems from some specific &lt;EM&gt;domain&lt;/EM&gt;. An example of such language (and an associated executor) is a block of code that is written as a linear code, but is executed asynchronously (in F# this can be implemented using &lt;EM&gt;computation expressions&lt;/EM&gt;), or a query that is written in F#, but is executed as a SQL code by some database server (this can be implemented using F# &lt;EM&gt;quotations&lt;/EM&gt;).&lt;/P&gt;
&lt;H2&gt;F# Overview - Links&lt;/H2&gt;
&lt;P&gt;In the rest of this article series we will look at all these three paradigms supported by F# starting with functional programming and basic F# types used when writing code in a functional way, continuing with object oriented programming and the support for .NET interoperability which is closely related to the OOP in F#. Lastly, we will look at the language oriented programming paradigm including some of the most important .NET and F# library functions that make it possible. The rest of the articles from the series are available in &lt;A href="http://tomasp.net/blog"&gt;my other blog&lt;/A&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://tomasp.net/articles/fsharp-i-introduction.aspx"&gt;F# Overview (I.) - Introduction&lt;/A&gt; (at TomasP.Net) 
&lt;LI&gt;&lt;A href="http://tomasp.net/articles/fsharp-ii-functional.aspx"&gt;F# Overview (II.) - Functional Programming&lt;/A&gt; (at TomasP.Net) 
&lt;LI&gt;&lt;A href="http://tomasp.net/articles/fsharp-iii-oop.aspx"&gt;F# Overview (III.) - Object Oriented and Imperative Programming &lt;/A&gt;(at TomasP.Net) 
&lt;LI&gt;&lt;A href="http://tomasp.net/articles/fsharp-iv-lang.aspx"&gt;F# Overview (IV.) - Language Oriented Programming&lt;/A&gt;(at TomasP.Net)&lt;/LI&gt;&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;You can also download the complete article as &lt;A href="http://tomasp.net/articles/fsharp-i-introduction/article.pdf"&gt;a single document&lt;/A&gt; (PDF).&lt;/LI&gt;&lt;/UL&gt;
&lt;H2&gt;Other F# Resources&lt;/H2&gt;
&lt;P&gt;There are many other places where you can find useful information about F#. First of all, there is an official F# web site [1] where you can find the language specification, documentation and other useful resources. There are also two books written about F# (one already published [2], second will be available soon [3]). Lastly, there are also a lot of community resources including an F# community web site with discussion board [4], wiki [5] and several blogs [6,7,8,9]. Finally, there are also some projects developed by the F# community that are available at CodePlex - the first one includes various F# code samples [9, 10] and the second is based on my thesis and tries to solve several web development problems [11].&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;[1] &lt;A href="http://research.microsoft.com/fsharp/"&gt;F# web site&lt;/A&gt; [&lt;A href="http://research.microsoft.com/fsharp/" target=_blank&gt;^&lt;/A&gt;] - Official F# homepage 
&lt;LI&gt;[2] &lt;A href="http://www.amazon.com/Expert-F-Don-Syme/dp/1590598504"&gt;Expert F#&lt;/A&gt; [&lt;A href="http://www.amazon.com/Expert-F-Don-Syme/dp/1590598504" target=_blank&gt;^&lt;/A&gt;] - Book by by Don Syme, Adam Granicz and Antonio Cisternino 
&lt;LI&gt;[3] &lt;A href="http://www.amazon.com/Foundations-F-Robert-Pickering/dp/1590597575"&gt;Foundations of F#&lt;/A&gt; [&lt;A href="http://www.amazon.com/Foundations-F-Robert-Pickering/dp/1590597575" target=_blank&gt;^&lt;/A&gt;] - Book by Robert Pickering 
&lt;LI&gt;[4] &lt;A href="/"&gt;hubFS: THE place for F#&lt;/A&gt; [&lt;A href="/" target=_blank&gt;^&lt;/A&gt;] - The F# community web site with blogs, forums, etc.. 
&lt;LI&gt;[5] &lt;A href="http://www.strangelights.com/fsharp/wiki/"&gt;F# Wiki Homepage&lt;/A&gt; [&lt;A href="http://www.strangelights.com/fsharp/wiki/" target=_blank&gt;^&lt;/A&gt;] - F# Wiki started by Robert Pickering 
&lt;LI&gt;[&amp;#54;] &lt;A href="http://blogs.msdn.com/dsyme/"&gt;Don Syme’s WebLog on F# and Other Research Projects&lt;/A&gt; [&lt;A href="http://blogs.msdn.com/dsyme/" target=_blank&gt;^&lt;/A&gt;] - Blog written by the F# language designer Don Syme 
&lt;LI&gt;[7] &lt;A href="http://www.strangelights.com/blog/"&gt;Robert Pickering’s Strange Blog&lt;/A&gt; [&lt;A href="http://www.strangelights.com/blog/" target=_blank&gt;^&lt;/A&gt;] - Blog of the "Foundations of F#" book author 
&lt;LI&gt;[&amp;#56;] &lt;A href="http://weblogs.asp.net/gbarnett/"&gt;Granville Barnett&lt;/A&gt; [&lt;A href="http://weblogs.asp.net/gbarnett/" target=_blank&gt;^&lt;/A&gt;] - Explorations in programming 
&lt;LI&gt;[9] &lt;A href="http://fsharpnews.blogspot.com/"&gt;F# News&lt;/A&gt; [&lt;A href="http://fsharpnews.blogspot.com/" target=_blank&gt;^&lt;/A&gt;] and &lt;A href="http://www.ffconsultancy.com/dotnet/fsharp/index.html"&gt;F#.NET Tutorials&lt;/A&gt; [&lt;A href="http://www.ffconsultancy.com/dotnet/fsharp/index.html" target=_blank&gt;^&lt;/A&gt;] by Jon Harrop 
&lt;LI&gt;[10] &lt;A href="http://www.codeplex.com/fsharpsamples"&gt;F# Samples&lt;/A&gt; [&lt;A href="http://www.codeplex.com/fsharpsamples" target=_blank&gt;^&lt;/A&gt;] - Contains code that demonstrate various F# language features 
&lt;LI&gt;[11] &lt;A href="http://www.codeplex.com/fswebtools"&gt;F# WebTools&lt;/A&gt; [&lt;A href="http://www.codeplex.com/fswebtools" target=_blank&gt;^&lt;/A&gt;] - Project that allows writing client/server Ajax web applications entirely in F#&lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=3924" width="1" height="1"&gt;</description></item><item><title>Software Development Engineer Positions on the F# team!</title><link>http://cs.hubfs.net/blogs/f_team/archive/2007/10/30/3900.aspx</link><pubDate>Tue, 30 Oct 2007 22:51:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:3900</guid><dc:creator>dsyme</dc:creator><slash:comments>4</slash:comments><description>&lt;P&gt;The F# team is &lt;A href="http://members.microsoft.com/careers/search/details.aspx?JobID=5DF7A6AB-80C5-41CB-9A8D-5B344C33AE1D"&gt;hiring&lt;/A&gt;! We have two positions open right now. The first is a &lt;A href="http://members.microsoft.com/careers/search/details.aspx?JobID=5DF7A6AB-80C5-41CB-9A8D-5B344C33AE1D"&gt;software development engineer&lt;/A&gt; specializing in Visual Studio and libraries.&amp;nbsp; The second is a &lt;A href="http://members.microsoft.com/careers/search/details.aspx?JobID=B36FFEB2-4C11-4B9C-9B3F-5B23CC604A7B&amp;amp;start=1&amp;amp;interval=10&amp;amp;SortCol=DatePosted"&gt;software development engineer in test&lt;/A&gt;. Some extracts from the job description for the first:&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;EM&gt;We’re looking for an exceptional developer to work on integration with the Visual Studio editor and debugger, and with Technical Computing libraries. You will be a key designer/engineer on our team, responsible for significant architecture investments, implementing key features, and participating in language design. You will be working with very strong architects, engineers and researchers, often working across organizational boundaries and with the developer community. &lt;BR&gt;&lt;BR&gt;To be successful on this team, you should possess rock solid design and development skills. You should have a strong track record of shipping secure, high quality software through all phases of the product cycle and have demonstrated successes in cross team partnerships. The ideal candidate will have 6 or more years of experience designing/shipping developer tools, strong functional (F#/Haskell/OCaml), C# and C++ coding skills, and a good understanding of Technical Computing. A MS or PhD degree in Computer Science or a related technical field is preferred. &lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The &lt;A href="http://members.microsoft.com/careers/search/details.aspx?JobID=5DF7A6AB-80C5-41CB-9A8D-5B344C33AE1D"&gt;full details of the position&lt;/A&gt; are up on the Microsoft site, along with how to apply. (The job is listed as "C# team" because the F# team is a small team in the C# org). The location&amp;nbsp;listed is "Redmond", but we'd be open to people looking to work in Cambridge UK for some of the time.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=3900" width="1" height="1"&gt;</description></item><item><title>Juergen van Gael on Asynchronous Workflows</title><link>http://cs.hubfs.net/blogs/f_team/archive/2007/10/18/3774.aspx</link><pubDate>Thu, 18 Oct 2007 21:55:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:3774</guid><dc:creator>dsyme</dc:creator><slash:comments>1</slash:comments><description>&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 10pt; TEXT-ALIGN: justify"&gt;&lt;FONT face=Calibri size=3&gt;&lt;EM&gt;[ During the summer the F# team at MSR Cambridge had the pleasure of having &lt;/EM&gt;&lt;A href="http://mlg.eng.cam.ac.uk/jurgen/"&gt;&lt;EM&gt;Juergen van Gael&lt;/EM&gt;&lt;/A&gt;&lt;EM&gt; working with us, prior to his starting a PhD at the University of Cambridge. Juergen looked at three topics: probabilisitic modelling with F#, some machine learning algorithms with the APG team, and topics in math libary support for F#.&amp;nbsp; &lt;/EM&gt;&lt;/FONT&gt;&lt;FONT face=Calibri size=3&gt;&lt;EM&gt;Before he left Juergen wrote up his expereiences of using asynchronous workflows to parallelize some math algorithms. Here's his write up! &lt;/EM&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 10pt; TEXT-ALIGN: justify"&gt;&lt;FONT face=Calibri size=3&gt;&lt;EM&gt;One caveat: asynchronous workflows can be used to do some simple CPU-intensive parallelizations, but have some overheads because at each step of the way we have to cater for the fact that tasks may be &lt;U&gt;asynchronous&lt;/U&gt;, and this often means using operating system synchronization resources ("WaitHandles") along the way. Libraries like &lt;/EM&gt;&lt;A href="http://msdn.microsoft.com/msdnmag/issues/07/10/futures/default.aspx"&gt;&lt;EM&gt;Parallel FX Futures&lt;/EM&gt;&lt;/A&gt;&lt;EM&gt;&amp;nbsp;will have great functionality for scheduling lots of &lt;U&gt;synchronous&lt;/U&gt; tasks, like many of the ones used below. Juergen wrote this up before we could really make heavy us of Parallel FX so his write up doesn't mention them.&lt;/EM&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 10pt; TEXT-ALIGN: justify"&gt;&lt;FONT face=Calibri size=3&gt;&lt;EM&gt;Basically, I'd say that as these technologies become widely used&amp;nbsp;you should assess the characteristics of your tasks and use the right scheduling machinery for the job. Do your tasks need to perform non-blocking network&amp;nbsp;or disk I/O? Then the .NET thread pool will likely have to be used in some way, because that's largely how .NET asynchronous I/O works, and F# asynchronous workflows are a reasonable way of doing this kind of programming. Are they simple synchronous computational tasks? Then Parallel FX Futures look like&amp;nbsp;the right machinery there. &lt;/EM&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 10pt; TEXT-ALIGN: justify"&gt;&lt;FONT face=Calibri size=3&gt;&lt;EM&gt;Anyway, over to Juergen! ]&lt;/EM&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 10pt; TEXT-ALIGN: justify"&gt;&lt;FONT face=Calibri size=3&gt;I want to draw your attention to a feature of F# that I’ve become to like very much: asynchronous workflows. As a machine learning researcher, I often run into the scenario where I need to read in a lot of data, run a number of independent tasks (potentially in parallel) and later compute some aggregate information. A very recent example required me to compute optimal parameters for a classifier; unfortunately I could not compute gradient information and decided to brute force search over a parameter grid. Evaluating the classifier for every parameter is independent of all other evaluations though and could be done in parallel. Although asynchronous workflows are designed for other purposes, they allow you to do just this. Asynchronous workflows are a mechanism in F# to setup a computation by describing small tasks and how these tasks depend on each other. The feature that got me excited was that it is extremely simple to describe parallel tasks. Onto an example!&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 10pt; TEXT-ALIGN: justify"&gt;&lt;FONT face=Calibri size=3&gt;One way to picture an asynchronous workflows is as a directed acyclic graph where every node describes a simple computation: in F# this is represented as an &lt;/FONT&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US"&gt;Async&amp;lt;’a&amp;gt; &lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;task.&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 10pt; TEXT-ALIGN: justify"&gt;&lt;FONT face="Courier New" size=3&gt;V1 = Z*Z&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\&lt;BR&gt;V2 = sin(Z)&amp;nbsp;&amp;nbsp;&amp;nbsp; ---&lt;/FONT&gt;&lt;FONT face="Courier New" size=3&gt;--&amp;gt;&amp;nbsp; R = V1 + V2 + V3&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=3&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /&lt;BR&gt;V3 = log(Z) ---/ &lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 10pt; TEXT-ALIGN: center" align=center&gt;&lt;SPAN style="mso-no-proof: yes; mso-fareast-language: EN-GB"&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 10pt; TEXT-ALIGN: justify"&gt;&lt;FONT face=Calibri size=3&gt;The graph above shows a simple numerical computation which could be described with asynchronous workflows. Assume Z has some value prior to executing the computation in the graph above. It should be clear that the computations of the three v’s are independent and can be done in parallel; only after all three are computed the computation can proceed by computing R. The code snippet below shows how to describe the workflow in F#:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;#light&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;let&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; evals =&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let&lt;/SPAN&gt; z = 4.0&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;[ async { &lt;SPAN style="COLOR: blue"&gt;do&lt;/SPAN&gt; printf &lt;SPAN style="COLOR: #a31515"&gt;"Computing z*z\n"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; z * z };&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;async { &lt;SPAN style="COLOR: blue"&gt;do&lt;/SPAN&gt; printf &lt;SPAN style="COLOR: #a31515"&gt;"Computing sin(z)\n"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; (sin z) };&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;async { &lt;SPAN style="COLOR: blue"&gt;do&lt;/SPAN&gt; printf &lt;SPAN style="COLOR: #a31515"&gt;"Computing log(z)\n"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; (log z) } ]&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;let&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; awr =&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;async { &lt;SPAN style="COLOR: blue"&gt;let!&lt;/SPAN&gt; vs = Async.Parallel evals&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;do&lt;/SPAN&gt; printf &lt;SPAN style="COLOR: #a31515"&gt;"Computing v1+v2+v3\n"&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt; (Array.fold_left (&lt;SPAN style="COLOR: blue"&gt;fun&lt;/SPAN&gt; a b &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;&lt;/SPAN&gt; a + b) 0.0 vs) }&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;let&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; R = Async.Run awr&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 10pt"&gt;&lt;SPAN style="FONT-SIZE: 9pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;printf &lt;SPAN style="COLOR: #a31515"&gt;"Result = %f\n"&lt;/SPAN&gt; R&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 10pt; TEXT-ALIGN: justify"&gt;&lt;FONT face=Calibri size=3&gt;First we initialize a variable &lt;/FONT&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;evals &lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;which references a list of asynchronous computation each &lt;I style="mso-bidi-font-style: normal"&gt;describing&lt;/I&gt; the computation of one v. It is important to note that no numerical computation is done at this point: we are just setting up the computation. Next we build another computation (&lt;/FONT&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;awr&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;) as a workflow by using the &lt;/FONT&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;Async.Parallel &lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;construct. This construct takes a sequence of asynchronous workflows, schedules all of them in parallel, waits for the results and returns those packaged in a list of &lt;/FONT&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US"&gt;Async&lt;/SPAN&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;SPAN&gt; &lt;/SPAN&gt;types. In the &lt;/FONT&gt;&lt;/FONT&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;awr&lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt; expression, we bind variable &lt;/FONT&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;vs &lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;to the contents of the &lt;/FONT&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-US"&gt;Async&lt;/SPAN&gt;&lt;FONT size=3&gt;&lt;FONT face=Calibri&gt;&lt;SPAN&gt; &lt;/SPAN&gt;type returned by the parallel computations. Again, I want to stress that at this point we have only setup the computation. Only when we execute &lt;/FONT&gt;&lt;/FONT&gt;&lt;SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;Async.Run &lt;/SPAN&gt;&lt;FONT face=Calibri size=3&gt;do we commit the runtime to evaluate the whole workflow and wait for its results. On my machine this results in the following output:&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;Computing z*z&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;Computing sin(z)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;Computing log(z)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;Computing v1+v2+v3&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 10pt"&gt;&lt;SPAN style="FONT-SIZE: 9pt; COLOR: black; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'"&gt;Result = 16.629492&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 10pt; TEXT-ALIGN: justify"&gt;&lt;FONT face=Calibri size=3&gt;Although the computation we setup and executed above is trivial I hope I conveyed to you that asynchronous workflows are an interesting way to describe a parallel computation. Here is a possible implementation of a parallel matrix multiplication using asynchronous workflows. Note that in this example we chose to parallelize the computation of rows, but different granularities are possible. (Do not consider this to be a high performance, parallel matrix multiplication but rather as a workflow example.)&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;open&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt; Microsoft.FSharp.Collections&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;let&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt; ParallelMultiply A B =&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let&lt;/SPAN&gt; n = Array2.length1 A&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let&lt;/SPAN&gt; C = Array2.create n n 0.0&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let&lt;/SPAN&gt; RowTask i =&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;async { &lt;SPAN style="COLOR: blue"&gt;do&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;for&lt;/SPAN&gt; j=0 &lt;SPAN style="COLOR: blue"&gt;to&lt;/SPAN&gt; n-1 &lt;SPAN style="COLOR: blue"&gt;do&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;for&lt;/SPAN&gt; k=0 &lt;SPAN style="COLOR: blue"&gt;to&lt;/SPAN&gt; n-1 &lt;SPAN style="COLOR: blue"&gt;do&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;C.[i,j] &amp;lt;- C.[i,j] + A.[i,k] * B.[k,j]&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;do&lt;/SPAN&gt; printf &lt;SPAN style="COLOR: #a31515"&gt;"Computing row %d\n"&lt;/SPAN&gt; i&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;let&lt;/SPAN&gt; p = Async.Parallel [ &lt;SPAN style="COLOR: blue"&gt;for&lt;/SPAN&gt; i &lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt; [0..n-1] &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;&lt;/SPAN&gt; RowTask i ] |&amp;gt; Async.Ignore&lt;SPAN style="COLOR: green"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Async.Run p&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;C&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;let&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt; n = 4&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;let&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt; rnd = System.Random()&lt;SPAN style="COLOR: green"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;let&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt; A = Array2.init n n (&lt;SPAN style="COLOR: blue"&gt;fun&lt;/SPAN&gt; i j &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;&lt;/SPAN&gt; rnd.NextDouble())&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;let&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt; B = Array2.init n n (&lt;SPAN style="COLOR: blue"&gt;fun&lt;/SPAN&gt; i j &lt;SPAN style="COLOR: blue"&gt;-&amp;gt;&lt;/SPAN&gt; rnd.NextDouble())&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;printf &lt;SPAN style="COLOR: #a31515"&gt;"%A\n"&lt;/SPAN&gt; A&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;printf &lt;SPAN style="COLOR: #a31515"&gt;"%A\n"&lt;/SPAN&gt; B&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-SIZE: 9pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;let&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt; C = ParMult A B&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0cm 0cm 10pt"&gt;&lt;SPAN style="FONT-SIZE: 9pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-ansi-language: EN-US"&gt;printf &lt;SPAN style="COLOR: #a31515"&gt;"%A\n"&lt;/SPAN&gt; C&lt;/SPAN&gt;&lt;SPAN style="FONT-SIZE: 9pt; LINE-HEIGHT: 115%"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=3774" width="1" height="1"&gt;</description></item><item><title>Somasegar Announces Productization of F#</title><link>http://cs.hubfs.net/blogs/roberts_strange_f_blog/archive/2007/10/17/3762.aspx</link><pubDate>Wed, 17 Oct 2007 13:31:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:3762</guid><dc:creator>Robert</dc:creator><slash:comments>8</slash:comments><description>&lt;P&gt;Somasegar, the head of the Developer Division at Microsoft, has announced the productization of F#. &lt;A href="http://blogs.msdn.com/somasegar/archive/2007/10/17/f-a-functional-programming-language.aspx"&gt;Read more about it here&lt;/A&gt;.&lt;/P&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=3762" width="1" height="1"&gt;</description></item><item><title>Building LINQ Queries in F# and C#</title><link>http://cs.hubfs.net/blogs/tomasp/archive/2007/10/15/dynamic_queries_csharp_and_fsharp.aspx</link><pubDate>Mon, 15 Oct 2007 19:49:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:3754</guid><dc:creator>tomasp</dc:creator><slash:comments>0</slash:comments><description>&lt;P&gt;&lt;EM&gt;My last post at the hubFS was an article that I wrote earlier to my personal blog and I wrote one more article some time ago that is related to F# and I wasn't posted here. The article is a part of a short series that discusses how the same LINQ-related problem can be solved in F# and in C# 3.0 (and in fact, my implementation of the C# version was largely motivated by the F# solution). Because I think that the articles are closely related, I'll write just a short summary here and add links to both articles available in my other blog.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;The articles deal with a problem how can one build a LINQ (database) query at runtime. A typical example of a query that developers want to build at runtime is a query where the user can modify the filtering condition (&lt;CODE&gt;where&lt;/CODE&gt; clause) - for example the application may want to allow combining several conditions, like &lt;CODE&gt;c.Country == &amp;lt;entered value&amp;gt;&lt;/CODE&gt; with &lt;CODE&gt;c.Name.StartsWith(&amp;lt;entered value&amp;gt;)&lt;/CODE&gt;. In addition you may want to allow combining these single conditions using various operators (at least &lt;CODE&gt;or&lt;/CODE&gt; and &lt;CODE&gt;and&lt;/CODE&gt;). &lt;/P&gt;
&lt;P&gt;The article about the F# version also shortly introduces the F# comprehensions and quotations that are used when writing LINQ queries using F#. Then it gives a few examples of using LINQ for database queries and finally, it fully describes the example that is shortly introduced below. In the article about the C# version, I described several extensions that are very useful when writing the queries in the F#-style as well as a solution that I use to allow a mechanism similar to F# holes (that are shortly introduced below). Finally, the F# article also contains a version of the FLINQ sample that is compatible with Visual Studio 2008 Beta 2.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://tomasp.net/articles/dynamic-flinq.aspx"&gt;Building LINQ Queries at Runtime in F#&lt;/A&gt; [&lt;A href="http://tomasp.net/articles/dynamic-flinq.aspx" target=_blank&gt;^&lt;/A&gt;] - Complete article at TomasP.Net 
&lt;LI&gt;&lt;A href="http://tomasp.net/articles/dynamic-linq-queries.aspx"&gt;Building LINQ Queries at Runtime in C#&lt;/A&gt; [&lt;A href="http://tomasp.net/articles/dynamic-linq-queries.aspx" target=_blank&gt;^&lt;/A&gt;] - Complete article at TomasP.Net&lt;/LI&gt;&lt;/UL&gt;
&lt;H2&gt;Building LINQ Queries at Runtime in F#&lt;/H2&gt;
&lt;P&gt;In F#, the queries are represented using &lt;EM&gt;quotations&lt;/EM&gt; which can be easily combined thanks to the support for &lt;EM&gt;holes&lt;/EM&gt; (written as underscore). The following example first defines two basic conditions (one of them always returns &lt;CODE&gt;true&lt;/CODE&gt; and the second returns &lt;CODE&gt;false&lt;/CODE&gt;). Later, we define two combinators for combining conditions using &lt;CODE&gt;||&lt;/CODE&gt; and &lt;CODE&gt;&amp;amp;&amp;amp;&lt;/CODE&gt; operators. Finally, we build a condition that is composed from several elementary conditions (stored in a dictionary called&amp;nbsp;&lt;CODE&gt;dict&lt;/CODE&gt;). To do this we can use the &lt;CODE&gt;Fold&lt;/CODE&gt; function which takes an initial condition and combines it with all the conditions in the dictionary:&lt;/P&gt;&lt;PRE&gt;&lt;SPAN class=rem&gt;// Basic conditions that always return true/false&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;let&lt;/SPAN&gt; falseCond = « &lt;SPAN class=kwrd&gt;fun&lt;/SPAN&gt; (c:Customer) &lt;SPAN class=op&gt;-&amp;gt;&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;false&lt;/SPAN&gt; »
&lt;SPAN class=kwrd&gt;let&lt;/SPAN&gt; trueCond  = « &lt;SPAN class=kwrd&gt;fun&lt;/SPAN&gt; (c:Customer) &lt;SPAN class=op&gt;-&amp;gt;&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;true&lt;/SPAN&gt;  »

&lt;SPAN class=rem&gt;// Condition combinators&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;let&lt;/SPAN&gt; (&lt;SPAN class=op&gt;|&lt;/SPAN&gt;&lt;SPAN class=op&gt;|&lt;/SPAN&gt;*) f g = « &lt;SPAN class=kwrd&gt;fun&lt;/SPAN&gt; (c:Customer) &lt;SPAN class=op&gt;-&amp;gt;&lt;/SPAN&gt; (&lt;SPAN class=op&gt;_&lt;/SPAN&gt; c) &lt;SPAN class=op&gt;|&lt;/SPAN&gt;&lt;SPAN class=op&gt;|&lt;/SPAN&gt; (&lt;SPAN class=op&gt;_&lt;/SPAN&gt; c) » f g
&lt;SPAN class=kwrd&gt;let&lt;/SPAN&gt; (&amp;amp;&amp;amp;*) f g = « &lt;SPAN class=kwrd&gt;fun&lt;/SPAN&gt; (c:Customer) &lt;SPAN class=op&gt;-&amp;gt;&lt;/SPAN&gt; (&lt;SPAN class=op&gt;_&lt;/SPAN&gt; c) &amp;amp;&amp;amp; (&lt;SPAN class=op&gt;_&lt;/SPAN&gt; c) » f g

&lt;SPAN class=rem&gt;// Which combinator will we use?&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;let&lt;/SPAN&gt; (^^) = &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; generateOr &lt;SPAN class=kwrd&gt;then&lt;/SPAN&gt; (&lt;SPAN class=op&gt;|&lt;/SPAN&gt;&lt;SPAN class=op&gt;|&lt;/SPAN&gt;*) &lt;SPAN class=kwrd&gt;else&lt;/SPAN&gt; (&amp;amp;&amp;amp;*)
  
&lt;SPAN class=rem&gt;// Build the expression by folding all items in a dictionary  &lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;let&lt;/SPAN&gt; expr = 
  dict.Fold(&lt;SPAN class=kwrd&gt;fun&lt;/SPAN&gt; key propSelector e &lt;SPAN class=op&gt;-&amp;gt;&lt;/SPAN&gt;
      Console.Write(&lt;SPAN class=str&gt;"Enter value for '{0}':\n&amp;gt; "&lt;/SPAN&gt;, key);
      &lt;SPAN class=kwrd&gt;let&lt;/SPAN&gt; enteredVal = Console.ReadLine();
          
      &lt;SPAN class=kwrd&gt;let&lt;/SPAN&gt; currentCond = 
        « &lt;SPAN class=kwrd&gt;fun&lt;/SPAN&gt; (c:Customer) &lt;SPAN class=op&gt;-&amp;gt;&lt;/SPAN&gt; ((&lt;SPAN class=op&gt;_&lt;/SPAN&gt; c):string).IndexOf(&lt;SPAN class=op&gt;_&lt;/SPAN&gt;:string) &amp;lt;&amp;gt; -1 » 
          propSelector « §enteredVal »
      (currentExpr ^^ e)) 
    (&lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; generateOr &lt;SPAN class=kwrd&gt;then&lt;/SPAN&gt; falseCond &lt;SPAN class=kwrd&gt;else&lt;/SPAN&gt; trueCond)
&lt;/PRE&gt;
&lt;H2&gt;Building LINQ Queries at Runtime in C#&lt;/H2&gt;
&lt;P&gt;In C# the representation of the lambda expression can be either a delegate (&lt;CODE&gt;Func&amp;lt;...&amp;gt;&lt;/CODE&gt;) or an expression tree (&lt;CODE&gt;Expression&amp;lt;Func&amp;lt;...&amp;gt;&amp;gt;&lt;/CODE&gt;) and the decision whether to generate a delegate or an expression tree depends on the expected type, which means that the code needs to define a type alias.&amp;nbsp;This is possible thanks to the &lt;CODE&gt;using&lt;/CODE&gt; statement (though this can be avoided by using helper functions, but in this example I'll instead use aliases). Primitive conditions are easy to define once we have a type alias &lt;CODE&gt;CustomerCondition&lt;/CODE&gt; (which stands for an expression tree of a lambda expression taking a &lt;CODE&gt;Customer&lt;/CODE&gt; as an argument and returning a &lt;CODE&gt;bool&lt;/CODE&gt;). When defining a combinators, we need a way for calling an expression tree in another expression tree and this is done by the method &lt;CODE&gt;Expand&lt;/CODE&gt; (which is not part of LINQ and is further discussed in the article). Finally, the code that generates the result uses similar technique as the previous F# version:&lt;/P&gt;&lt;PRE&gt;&lt;SPAN class=rem&gt;// Basic conditions that always return true/false&lt;/SPAN&gt;
CustomerCondition trueCond  = (c) =&amp;gt; &lt;SPAN class=kwrd&gt;true&lt;/SPAN&gt;;
CustomerCondition falseCond = (c) =&amp;gt; &lt;SPAN class=kwrd&gt;false&lt;/SPAN&gt;;

&lt;SPAN class=rem&gt;// Condition combinators&lt;/SPAN&gt;
CustomerConditionCombinator combineOr = 
  (f, g) =&amp;gt; (c) =&amp;gt; f.Expand(c) || g.Expand(c);
CustomerConditionCombinator combineAnd = 
  (f, g) =&amp;gt; (c) =&amp;gt; f.Expand(c) &amp;amp;&amp;amp; g.Expand(c);

&lt;SPAN class=rem&gt;// Which combinator will we use?&lt;/SPAN&gt;
CustomerConditionCombinator combinator = 
  generateOr ? combineOr : combineAnd;

&lt;SPAN class=rem&gt;// Build the expression by folding all items in a dictionary  &lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;var&lt;/SPAN&gt; expr = dict.Fold((e, item) =&amp;gt; {
    Console.Write(&lt;SPAN class=str&gt;"Enter value for '{0}':\n&amp;gt; "&lt;/SPAN&gt;, item.Key);
    &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; enteredVal = Console.ReadLine();
    CustomerPropSelector propSelector = item.Value;    
    
    CustomerCondition currentCond = (c) =&amp;gt; 
      propSelector.Expand(c).IndexOf(enteredVal) != -1;
      
    &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; combinator(e, currentCond); 
  }, generateOr ? falseCond : trueCond);
&lt;/PRE&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=3754" width="1" height="1"&gt;</description></item><item><title>F# Web Tools: &amp;quot;Ajax&amp;quot; applications made simple</title><link>http://cs.hubfs.net/blogs/tomasp/archive/2007/10/13/fsharp_webtools_intro.aspx</link><pubDate>Sat, 13 Oct 2007 20:23:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:3744</guid><dc:creator>tomasp</dc:creator><slash:comments>6</slash:comments><description>I started thinking about working on "Ajax" framework quite a long time ago - the key thing I really wanted from the beginning was using the same language for writing both client and server side code and the integration between these two sides, so you could write an event handler and specify if it should be executed on the client or on the server side. About a year ago I visited Cambridge (thanks to the MVP program) and I had a chance to talk with Don Syme [^]. Don showed me a few things in F# and suggested using F# for this project, so when I was later selected to do an internship at MSR, this was one of the projects that I wanted to work on.

The original reason for using F# was its support for meta-programming ([8], which makes it extremely easy to translate part of the page code-behind code to JavaScript. During my internship, the F# team was also working on a feature called computational expressions, which proved to be extremely useful for the F# Web Tools as well - I bet you'll hear a lot about this from Don soon, so I'll describe only the aspects that are important for this project. Aside from these two key features that F# has, I also quite enjoyed programming in F# itself - I already used it for a few things during the last year, but I could finally work on a large project in F# (and discuss the solution with the real experts!) and I don't believe I would be able to finish the project of similar complexity during less than three months in any other language (but this is a different topic, which deserves separate blog post). ...(&lt;a href="http://cs.hubfs.net/blogs/tomasp/archive/2007/10/13/fsharp_webtools_intro.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=3744" width="1" height="1"&gt;</description></item><item><title>CUFP Workshop 2007 - Featuring F#</title><link>http://cs.hubfs.net/blogs/f_team/archive/2007/08/21/3548.aspx</link><pubDate>Tue, 21 Aug 2007 17:09:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:3548</guid><dc:creator>dsyme</dc:creator><slash:comments>0</slash:comments><description>&lt;P&gt;The program for the 2007 Commercial Users of Functional Programming workshop is now published.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;A href="http://cufp.galois.com/"&gt;http://cufp.galois.com/&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;The workshop is co-located with ICFP, and will be held in Freiburg, Germany, on 4 October 2007.&amp;nbsp; We had a terrific response to our call for talks, and there are twelve (!) speakers describing commercial applications,&amp;nbsp; variously written in&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Caml&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Erlang&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; F#&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Haskell&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ML&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Scheme&lt;/P&gt;
&lt;P&gt;The talks are informal, and there are no proceedings.&amp;nbsp; We'll just have fun learning about functional programming used to solve real problems.&amp;nbsp; Do come!&lt;/P&gt;
&lt;P&gt;Don Syme&lt;BR&gt;Kathleen Fisher&lt;BR&gt;Simon Peyton Jones&lt;BR&gt;&lt;/P&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=3548" width="1" height="1"&gt;</description></item><item><title>F# on Hansel Minutes</title><link>http://cs.hubfs.net/blogs/roberts_strange_f_blog/archive/2007/08/10/3497.aspx</link><pubDate>Fri, 10 Aug 2007 13:54:00 GMT</pubDate><guid isPermaLink="false">7372db05-f90c-40e3-82a2-789ed9f521c9:3497</guid><dc:creator>Robert</dc:creator><slash:comments>0</slash:comments><description>Listen to yours truely bang on about F# for 36 minutes and 22 seconds :)&lt;BR&gt;&lt;A href="http://hanselminutes.com/default.aspx?showID=94"&gt;http://hanselminutes.com/default.aspx?showID=94&lt;/A&gt;&lt;img src="http://cs.hubfs.net/aggbug.aspx?PostID=3497" width="1" height="1"&gt;</description></item></channel></rss>