<?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>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>1</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>6</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>3</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>3</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>17</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>4</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 what