<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Matt&#039;s Software Blog</title>
	<atom:link href="http://www.mattssoftwareblog.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.mattssoftwareblog.com</link>
	<description></description>
	<lastBuildDate>Sun, 15 Aug 2010 20:15:28 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='www.mattssoftwareblog.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
		<item>
		<title>Undo / Redo using the Memento Pattern and Command Pattern in F#</title>
		<link>http://www.mattssoftwareblog.com/?p=246</link>
		<comments>http://www.mattssoftwareblog.com/?p=246#comments</comments>
		<pubDate>Sun, 15 Aug 2010 20:14:04 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.mattssoftwareblog.com/?p=246</guid>
		<description><![CDATA[This project tackles the problem off managing undo functionality.  It leverages the F# Actor model to implement the Memento pattern, and uses functions as first class objects to implement the Command pattern. This code takes functionality that is ostensibly quite difficult and makes it much easier.
Code&#8230;


#light

#r &#34;FSharp.Core&#34;
#r &#34;PresentationCore&#34;
#r &#34;PresentationFramework&#34;
#r &#34;WindowsBase&#34;
#r &#34;System.Xaml&#34;

open System
open System.Linq
open System.Windows
open System.Windows.Input
open [...]]]></description>
			<content:encoded><![CDATA[<p>This project tackles the problem off managing undo functionality.  It leverages the F# Actor model to implement the Memento pattern, and uses functions as first class objects to implement the Command pattern. This code takes functionality that is ostensibly quite difficult and makes it much easier.</p>
<div id="attachment_247" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.mattssoftwareblog.com/wp-content/uploads/2010/08/UndoRedoFSharp.png" rel="shadowbox[post-246];player=img;"><img class="size-medium wp-image-247" title="Undo Redo in F#" src="http://www.mattssoftwareblog.com/wp-content/uploads/2010/08/UndoRedoFSharp-300x228.png" alt="Undo Redo in F#" width="300" height="228" /></a><p class="wp-caption-text">Undo Redo in F#</p></div>
<p>Code&#8230;</p>
<p><span id="more-246"></span></p>
<pre class="brush: plain;">
#light

#r &quot;FSharp.Core&quot;
#r &quot;PresentationCore&quot;
#r &quot;PresentationFramework&quot;
#r &quot;WindowsBase&quot;
#r &quot;System.Xaml&quot;

open System
open System.Linq
open System.Windows
open System.Windows.Input
open System.Windows.Controls
open System.Windows.Data
open System.ComponentModel
open System.Windows.Shapes
open System.Windows.Media
open System.Xaml
open System.IO
open System.Text
open System.Windows.Markup
open System.Threading

type Command = string * (unit -&gt; unit) * (unit -&gt; unit)

type MementoMessage =
    | UndoList of string seq AsyncReplyChannel
    | RedoList of string seq AsyncReplyChannel
    | UndoCommand
    | RedoCommand
    | Clear
    | NewCommand of Command
    | CanUndo of bool AsyncReplyChannel
    | CanRedo of bool AsyncReplyChannel

type Memento() as this =

    let (&lt;--) (m:'msg MailboxProcessor) x = m.Post x
    let (&lt;-&gt;) (m:_ MailboxProcessor) msg = m.PostAndReply(fun replyChannel -&gt; msg replyChannel)

    let emptyStack = List&lt;string * (unit -&gt; unit) * (unit -&gt; unit)&gt;.Empty

    let memento = new MailboxProcessor&lt;MementoMessage&gt;(fun inbox -&gt;
        let rec loop undoStack redoStack =
            async { let! msgOption = inbox.TryReceive(timeout=0)
                    match msgOption with
                    | None -&gt;
                        do! Async.Sleep(20)
                        return! loop undoStack redoStack
                    | Some(msg) -&gt;
                       match msg with
                       | CanUndo replyChannel  -&gt;
                            replyChannel.Reply (undoStack |&gt; List.isEmpty |&gt; not)
                            return! loop undoStack redoStack
                       | CanRedo replyChannel  -&gt;
                            replyChannel.Reply (redoStack |&gt; List.isEmpty |&gt; not)
                            return! loop undoStack redoStack
                       | UndoList replyChannel -&gt;
                            replyChannel.Reply (undoStack |&gt; List.map (fun (name,_,_) -&gt; name))
                            return! loop undoStack redoStack
                       | RedoList replyChannel -&gt;
                            replyChannel.Reply (redoStack |&gt; List.map (fun (name,_,_) -&gt; name))
                            return! loop undoStack redoStack
                       | UndoCommand -&gt;
                            if (undoStack |&gt; List.isEmpty) then return! loop undoStack redoStack // ignore
                                else
                                    let (_, undo, _) = List.head undoStack
                                    undo()
                                    return! loop (List.tail undoStack) ((List.head undoStack)::redoStack)
                       | RedoCommand -&gt;
                            if (redoStack |&gt; List.isEmpty) then return! loop undoStack redoStack
                                else
                                   let (_, _, redo) = List.head redoStack
                                   redo()
                                   return! loop ((List.head redoStack)::undoStack) (List.tail redoStack)
                       | NewCommand command   -&gt;
                           return! loop (command::undoStack) emptyStack
                       | Clear -&gt;
                           return! loop emptyStack emptyStack
                }

        loop emptyStack emptyStack
        )

    do
        memento.Start()

    let propertyChanged = Event&lt;_,_&gt;()
    let notify obj s = propertyChanged.Trigger(obj, PropertyChangedEventArgs(s))

    let notifyAll() = [|&quot;CanUndo&quot;;&quot;CanRedo&quot;;&quot;UndoList&quot;;&quot;RedoList&quot;|] |&gt; Array.iter (fun s -&gt; notify this s)

    interface INotifyPropertyChanged with
       [&lt;CLIEvent&gt;]
       member this.PropertyChanged = propertyChanged.Publish

    member this.NewCommand(command:Command) = memento &lt;-- NewCommand(command); notifyAll()
    member this.Undo() = memento &lt;-- UndoCommand; notifyAll()
    member this.Redo() = memento &lt;-- RedoCommand; notifyAll()
    member this.Clear() = memento &lt;-- Clear
    member this.CanUndo with get()  = memento &lt;-&gt; CanUndo
    member this.CanRedo with get()  = memento &lt;-&gt; CanRedo
    member this.UndoList with get() = memento &lt;-&gt; UndoList
    member this.RedoList with get() = memento &lt;-&gt; RedoList

let window = &quot;&lt;Window
        xmlns=\&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation\&quot;
        xmlns:x=\&quot;http://schemas.microsoft.com/winfx/2006/xaml\&quot;
        Title=\&quot;MainWindow\&quot; Height=\&quot;400\&quot; Width=\&quot;525\&quot;&gt;
    &lt;DockPanel&gt;
        &lt;StackPanel DockPanel.Dock=\&quot;Left\&quot; Width=\&quot;150\&quot;&gt;
            &lt;Button x:Name=\&quot;redButton\&quot;&gt;Red&lt;/Button&gt;
            &lt;Button x:Name=\&quot;greenButton\&quot;&gt;Green&lt;/Button&gt;
            &lt;Button x:Name=\&quot;blueButton\&quot;&gt;Blue&lt;/Button&gt;
            &lt;Button IsEnabled=\&quot;{Binding CanUndo}\&quot; x:Name=\&quot;undoButton\&quot;&gt;Undo&lt;/Button&gt;
            &lt;Button IsEnabled=\&quot;{Binding CanRedo}\&quot; x:Name=\&quot;redoButton\&quot;&gt;Redo&lt;/Button&gt;
            &lt;Label&gt;Undo List:&lt;/Label&gt;
            &lt;ListBox x:Name=\&quot;undoListBox\&quot; MinHeight=\&quot;100\&quot; ItemsSource=\&quot;{Binding UndoList}\&quot;&gt;&lt;/ListBox&gt;
            &lt;Label&gt;Redo List:&lt;/Label&gt;
            &lt;ListBox x:Name=\&quot;redoListBox\&quot; MinHeight=\&quot;100\&quot; ItemsSource=\&quot;{Binding RedoList}\&quot;&gt;&lt;/ListBox&gt;
        &lt;/StackPanel&gt;
        &lt;Grid x:Name=\&quot;grid\&quot; Background=\&quot;Red\&quot; /&gt;
    &lt;/DockPanel&gt;
&lt;/Window&gt;&quot; |&gt; XamlReader.Parse :?&gt; Window

let memento = new Memento()
window.DataContext &lt;- memento

let redButton = window.FindName(&quot;redButton&quot;) :?&gt; Button
let greenButton = window.FindName(&quot;greenButton&quot;) :?&gt; Button
let blueButton = window.FindName(&quot;blueButton&quot;) :?&gt; Button
let undoButton = window.FindName(&quot;undoButton&quot;) :?&gt; Button
let redoButton = window.FindName(&quot;redoButton&quot;) :?&gt; Button

let grid = window.FindName(&quot;grid&quot;) :?&gt; Grid

let context = AsyncOperationManager.SynchronizationContext
let runInGuiContext f =
    context.Post(new SendOrPostCallback(fun _ -&gt; f()),null)

let changeBackground(name:string, brush:Brush) =
    let old = grid.Background
    memento.NewCommand((name, (fun _ -&gt; runInGuiContext(fun _ -&gt; grid.Background &lt;- old)), (fun _ -&gt; runInGuiContext(fun _ -&gt; grid.Background &lt;- brush))))
    grid.Background &lt;- brush

redButton.Click.Add(fun _ -&gt;  changeBackground(&quot;-&gt; Red&quot;, Brushes.Red))
greenButton.Click.Add(fun _ -&gt; changeBackground(&quot;-&gt; Green&quot;, Brushes.Green))
blueButton.Click.Add(fun _ -&gt; changeBackground(&quot;-&gt; Blue&quot;, Brushes.Blue))

undoButton.Click.Add(fun _ -&gt; memento.Undo())
redoButton.Click.Add(fun _ -&gt; memento.Redo())

window.Show()
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.mattssoftwareblog.com/?feed=rss2&amp;p=246</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Dynamically extending applications using MEF and the new F# CodeDom</title>
		<link>http://www.mattssoftwareblog.com/?p=233</link>
		<comments>http://www.mattssoftwareblog.com/?p=233#comments</comments>
		<pubDate>Sun, 21 Mar 2010 21:27:06 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[CodeDom]]></category>
		<category><![CDATA[F#]]></category>
		<category><![CDATA[MEF]]></category>

		<guid isPermaLink="false">http://www.mattssoftwareblog.com/?p=233</guid>
		<description><![CDATA[Hi folks,
I wrote this little applet to see what the combination of MEF and the F# CodeDom would look like, and for the record it looks really really good.
This combination opens a whole lot of doors. By using the F# CodeDom the plugin source code can brought in from anywhere;

A server,
A blog,
Code generated from a [...]]]></description>
			<content:encoded><![CDATA[<p>Hi folks,</p>
<p>I wrote this little applet to see what the combination of MEF and the F# CodeDom would look like, and for the record it looks really really good.</p>
<p>This combination opens a whole lot of doors. By using the F# CodeDom the plugin source code can brought in from anywhere;</p>
<ul>
<li>A server,</li>
<li>A blog,</li>
<li>Code generated from a DSL, or even</li>
<li>Entered by the user directly.</li>
</ul>
<p>See below for the implementation.</p>
<p><a href="http://blogs.msdn.com/jomo_fisher/archive/2010/03/09/neat-samples-extend-your-f-program-with-mef.aspx">Basic MEF Code</a> originally from Jomo Fisher</p>
<pre class="brush: plain;">
open System.Reflection
open System.IO
open System.ComponentModel.Composition
open System.ComponentModel.Composition.Hosting
open Microsoft.FSharp.Compiler.CodeDom
open System.CodeDom.Compiler
open System.Linq
open System.Collections

open MEF_Interface
// Set up catalog
let catalog = new AggregateCatalog()
let directoryCatalog = new DirectoryCatalog(@&quot;c:\Extensions&quot;,&quot;*.dll&quot;)

let container = new CompositionContainer(catalog)
catalog.Catalogs.Add(directoryCatalog)

// Jar that will contain tasty treats
type TreatJar() =
    [&lt;ImportMany(typeof&lt;ITastyTreat&gt;)&gt;]
    let cookies : seq&lt;ITastyTreat&gt; = null

    member this.EatTreats() =
        cookies |&gt; Seq.iter (fun tt -&gt; printfn &quot;Yum, it was a %s&quot; tt.Description)

let jar = TreatJar()

// Build plugin from string
let fs = new FSharpCodeProvider()
let parameters = new CompilerParameters([|@&quot;C:\Users\moloneymb\Documents\Visual Studio 2010\Projects\MEF\MEF Interface\bin\Debug\MEF_Interface.dll&quot;;&quot;System.ComponentModel.Composition.dll&quot;;&quot;System.Core.dll&quot;|], &quot;test.dll&quot;, true)
parameters.GenerateExecutable &lt;- false
let m = &quot;
namespace ChocolateCookie
open System.ComponentModel.Composition
open MEF_Interface

[&lt;Export(typeof&lt;ITastyTreat&gt;)&gt;]
type ChocolateCookie() =
    interface ITastyTreat with
        member this.Description = \&quot;a delicious chocolate cookie\&quot;&quot;

let result = fs.CompileAssemblyFromSource(parameters,m)
for e in result.Errors do System.Console.WriteLine(e.ToString())
for o in result.Output do System.Console.WriteLine(o)

// Copy plug-in to container path
File.Copy(@&quot;C:\Users\moloneymb\Documents\Visual Studio 2010\Projects\MEF\MEF\bin\Debug\test.dll&quot;,@&quot;c:\Extensions\test.dll&quot;)

// Wait for transfer
System.Console.ReadKey() |&gt; ignore

// Refresh directory catalog to pick up the new plug-in
directoryCatalog.Refresh()

// Run plug-ins
container.ComposeParts(jar)
jar.EatTreats()

// Wait to close
System.Console.ReadKey() |&gt; ignore

// Delete file so we can re-run this program later
File.Delete(@&quot;c:\Extensions\test.dll&quot;)
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.mattssoftwareblog.com/?feed=rss2&amp;p=233</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Drag and Drop using Rx and WPF in F#</title>
		<link>http://www.mattssoftwareblog.com/?p=227</link>
		<comments>http://www.mattssoftwareblog.com/?p=227#comments</comments>
		<pubDate>Thu, 11 Mar 2010 07:56:23 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[F#]]></category>
		<category><![CDATA[Rx]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.mattssoftwareblog.com/?p=227</guid>
		<description><![CDATA[Hi folks,
I have recently been experimenting with combining Reactive X, WPF, and F# and have found the combination to be very palatable. I chose drag and drop as the test case because it is both non trivial and generally deeply stateful. The resulting Rx turns out to be one fifth the code of my original [...]]]></description>
			<content:encoded><![CDATA[<p>Hi folks,</p>
<p>I have recently been experimenting with combining Reactive X, WPF, and F# and have found the combination to be very palatable. I chose drag and drop as the test case because it is both non trivial and generally deeply stateful. The resulting Rx turns out to be one fifth the code of my original C#, much easier to read and has fewer errors.</p>
<p><a href="http://www.mattssoftwareblog.com/wp-content/uploads/2010/03/Event-Sample.png" rel="shadowbox[post-227];player=img;"><img class="aligncenter size-thumbnail wp-image-229" title="Event Sample" src="http://www.mattssoftwareblog.com/wp-content/uploads/2010/03/Event-Sample-150x150.png" alt="" width="150" height="150" /></a></p>
<p>Drag and Drop code:</p>
<pre class="brush: plain;">
    leftDown
        |&gt; map (fun e1 -&gt; (e1, mouseMove |&gt; takeUntil leftUp |&gt; takeUntil mouseLeave))
        |&gt; filter (fun (e1, e2s) -&gt; e1.Source.Equals(canvas) |&gt; not)
        |&gt; map (fun (e1, e2s) -&gt;
                        let control = e1.Source :?&gt; UIElement
                        let leftTop = (Canvas.GetLeft(control), Canvas.GetTop(control))
                        let pt1 = e1.GetPosition(canvas)
                        e2s |&gt; map (fun e2 -&gt;
                                        let pt2 = e2.GetPosition(canvas)
                                        (control, leftTop, pt2 - pt1)))
        |&gt; mergeAll
        |&gt; subscribe (fun (control, (left,top), delta) -&gt; Canvas.SetLeft(control, left + delta.X); Canvas.SetTop(control, top + delta.Y))
</pre>
<p>As always, I am interested in feedback.</p>
<p>Cheers,</p>
<p>Matt</p>
<p>Full Code:</p>
<p><span id="more-227"></span></p>
<pre class="brush: plain;">
open System
open System.Linq
open System.Windows
open System.Windows.Input
open System.Windows.Controls
open System.Windows.Shapes
open System.Windows.Media
open System.Xaml
open System.IO
open System.Text
open System.Windows.Markup

let parseXAML (xaml : string) =
    use ms = new MemoryStream(Encoding.ASCII.GetBytes(xaml))
    ms.Position &lt;- int64 0
    XamlReader.Load(ms)

// helper functions from Steffen Forkmann (http://www.navision-blog.de)
let asAction f = new System.Action(f)

let doNothing = asAction (fun () -&gt; ())

let create f =
    Observable.Create&lt;_&gt;(fun x -&gt;
        f x
        doNothing)

let fromEvent (event:IEvent&lt;_,_&gt;) = create (fun x -&gt; event.Add x.OnNext)

let mergeAll (observables:IObservable&lt;IObservable&lt;'a&gt;&gt;) = Observable.Merge observables

let map f observable = Observable.Select(observable, Func&lt;_,_&gt;(f))

let takeUntil other source = Observable.TakeUntil(source,other)

let filter f observable = Observable.Where(observable, Func&lt;_,_&gt;(f))

let subscribeComplete next error completed (obs: IObservable&lt;'a&gt;) =
    obs.Subscribe(
        (fun x -&gt; next x),
        (fun e -&gt; error e),
        (fun () -&gt; completed()))

let subscribeWithError next error obs =
    subscribeComplete next error (fun () -&gt; ()) obs

let subscribe next obs =
    subscribeWithError next ignore obs

let window =
    let window =
        &quot;&lt;Window
            xmlns=\&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation\&quot;
            xmlns:x=\&quot;http://schemas.microsoft.com/winfx/2006/xaml\&quot;
            Title=\&quot;Event Sample\&quot; Height=\&quot;200\&quot; Width=\&quot;200\&quot;&gt;
        &lt;Canvas x:Name=\&quot;canvas\&quot; Background=\&quot;LightBlue\&quot;&gt;
            &lt;Rectangle Canvas.Left=\&quot;50\&quot; Canvas.Top=\&quot;50\&quot;  Fill=\&quot;Red\&quot; Height=\&quot;50\&quot; Width=\&quot;50\&quot; /&gt;
            &lt;TextBlock Canvas.Left=\&quot;50\&quot; Canvas.Top=\&quot;120\&quot;   Text=\&quot;Hello World!\&quot; /&gt;
        &lt;/Canvas&gt;
    &lt;/Window&gt;&quot; |&gt; parseXAML :?&gt; Window
    let canvas = window.FindName(&quot;canvas&quot;) :?&gt; Canvas

    let leftDown = canvas.MouseLeftButtonDown  |&gt; fromEvent
    let leftUp   = canvas.MouseLeftButtonUp    |&gt; fromEvent
    let mouseMove = canvas.MouseMove           |&gt; fromEvent
    let mouseLeave = canvas.MouseLeave         |&gt; fromEvent

    leftDown
        |&gt; map (fun e1 -&gt; (e1, mouseMove |&gt; takeUntil leftUp |&gt; takeUntil mouseLeave))
        |&gt; filter (fun (e1, e2s) -&gt; e1.Source.Equals(canvas) |&gt; not)
        |&gt; map (fun (e1, e2s) -&gt;
                        let control = e1.Source :?&gt; UIElement
                        let leftTop = (Canvas.GetLeft(control), Canvas.GetTop(control))
                        let pt1 = e1.GetPosition(canvas)
                        e2s |&gt; map (fun e2 -&gt;
                                        let pt2 = e2.GetPosition(canvas)
                                        (control, leftTop, pt2 - pt1)))
        |&gt; mergeAll
        |&gt; subscribe (fun (control, (left,top), delta) -&gt; Canvas.SetLeft(control, left + delta.X); Canvas.SetTop(control, top + delta.Y))
        |&gt; ignore

    window

let main() =
    let app = new Application()
    app.Run(window) |&gt; ignore

[&lt;STAThread&gt;]
    do main()
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.mattssoftwareblog.com/?feed=rss2&amp;p=227</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Azure F# Worker Role with WCF</title>
		<link>http://www.mattssoftwareblog.com/?p=219</link>
		<comments>http://www.mattssoftwareblog.com/?p=219#comments</comments>
		<pubDate>Mon, 23 Nov 2009 07:36:41 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.mattssoftwareblog.com/?p=219</guid>
		<description><![CDATA[Azure now has support for input endpoints on Worker Roles! (Azure Tools Nov 2009) This is awesome as it greatly simplifies building WCF services in the cloud. David Aiken has written an excellent Channel 9 post on exactly how to do this (here).
As per usual, I’ve gone ahead and ported the most important components to [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_223" class="wp-caption aligncenter" style="width: 310px"><img class="size-medium wp-image-223" title="Azure WCF Test" src="http://www.mattssoftwareblog.com/wp-content/uploads/2009/11/AzureTest-300x228.PNG" alt="Quick test of the Azure WCF service" width="300" height="228" /><p class="wp-caption-text">Quick test of the Azure WCF service</p></div>
<p>Azure now has support for input endpoints on Worker Roles! (<a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=6967ff37-813e-47c7-b987-889124b43abd&amp;displaylang=en">Azure Tools Nov 2009</a>) This is awesome as it greatly simplifies building WCF services in the cloud. David Aiken has written an excellent Channel 9 post on exactly how to do this (<a href="http://channel9.msdn.com/learn/courses/Azure/WindowsAzure/WindowsAzureRoleCommunicationLab/">here</a>).</p>
<p>As per usual, I’ve gone ahead and ported the most important components to F# and I have included a short list of some of the difficulties I had while doing so.</p>
<p>Lessons Learned;</p>
<p>1. In Azure, you cannot just specify the input endpoints in code, you have to specify the endpoints in the properties for the role. It will work in the Dev fabric but will not initialize in the cloud. (thanks to <a href="http://social.msdn.microsoft.com/Forums/en-US/windowsazure/thread/43c4dd53-b8fe-46d5-9252-940d4c933f62/">Daniel C Wang</a>)</p>
<p>Wrong:</p>
<pre class="brush: csharp;">
 let baseAddress = Uri(&quot;http://kapow.cloudapp.net:8080/service&quot;)
 let myServiceHost = new ServiceHost((typeof&lt;GreetingService&gt;), [|baseAddress|])
</pre>
<p>Right:</p>
<pre class="brush: csharp;">
using Microsoft.WindowsAzure.SerivceRuntime;

var listenAddress = RoleEnvironment
    .CurrentInstance
    .InstanceEndpoint[&quot;&lt;name of your input endpoint &gt;&quot;]
    .IPEndpoint;

string uri = String.Format(&quot;http://{0}&quot; ,listenAddress)
</pre>
<p>2. TryGetValue can return the value in a 2-tuple instead of by ref &#8211; this makes it a lot more F# friendly. (from <a href="http://msdn.microsoft.com/en-us/library/dd233213(VS.100).aspx">here</a>)</p>
<p>This:</p>
<pre class="brush: csharp;">
SessionInformation session;
bool exists = sessions.TryGetValue(sessionId, out session)
</pre>
<p>Becomes this:</p>
<pre class="brush: csharp;">
let (exists,session) = sessions.TryGetValue(sessionId)
</pre>
<p>3. KnownTypes &#8211; By default, you cannot use a subclass of a data contract class instead of its base class. This took me a while to figure out. (From Programming WCF Services &#8211; O&#8217;Reilly)</p>
<p>In C#:</p>
<pre class="brush: csharp;">
[DataContract]
[KnownType(typeof(Custoemr))]
class Contact
{..}

[DataContract]
Class Customer : Contact
{..}
</pre>
<p>4. You have to take down an Azure deployment in order to change the input endpoints, so no in place upgrades with new endpoints. The Dr. Watson error for this wasn&#8217;t very clear.</p>
<p>Things I still can&#8217;t figure out;</p>
<p>I am assuming that the <span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; line-height: 18px; font-size: 12px; white-space: pre;">ICommunicationObject <span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; line-height: 19px; white-space: normal; font-size: 13px;">interface is added by an attribute, I just can&#8217;t cast to it. I get an invalid cast error at runtime. I need to do this, so if anyone knows how, please let me know.</span></span></p>
<p>In C#:</p>
<pre class="brush: csharp;">
((ICommunicationObject)client).Abort();
</pre>
<p>In F#: (from <a href="http://cs.hubfs.net/forums/thread/3616.aspx">here</a>)</p>
<pre class="brush: csharp;">
(box client :?&gt; ICommunicationObject).Abort()
</pre>
<p>The Code:<br />
<span id="more-219"></span></p>
<p>The contract:</p>
<pre class="brush: csharp;">
namespace AzureTalk.Contract

open System
open System.Collections.Generic
open System.ServiceModel
open System.Runtime.Serialization

[&lt;DataContract(Namespace = &quot;urn:WindowsAzurePlatformKit:Labs:AzureTalk:2009:10:schemas&quot;)&gt;]
[&lt;KnownType(typeof&lt;SessionInformation&gt;)&gt;]
type ClientInformation =
        [&lt;DataMember&gt;]
        val mutable SessionId : string

        [&lt;DataMember&gt;]
        val mutable UserName : string

        [&lt;DataMember&gt;]
        val mutable RoleId : string

        [&lt;DataMember&gt;]
        val mutable IsActive : bool

        new(sessionId, userName, roleId) =
            {
                SessionId = sessionId
                UserName = userName
                RoleId = roleId
                IsActive = true
            }

and [&lt;DataContract(Namespace = &quot;urn:WindowsAzurePlatformKit:Labs:AzureTalk:2009:10&quot;)&gt;]
    SessionInformation =
    inherit ClientInformation

        [&lt;IgnoreDataMember&gt;]
        val mutable Callback : IClientNotification option

    new(sessionId, userName, roleId, isActive, callback) =
            {   inherit ClientInformation(sessionId, userName, roleId)
                Callback = callback
            }

and [&lt;ServiceContract(Namespace = &quot;urn:WindowsAzurePlatformKit:Labs:AzureTalk:2009:10&quot; )&gt;]
     IClientNotification =

    [&lt;OperationContract(IsOneWay = true)&gt;]
    abstract DeliverMessage : message:string -&gt; fromSessionId:string -&gt; toSessionId:string -&gt; Unit

    [&lt;OperationContract(IsOneWay = true)&gt;]
    abstract UpdateClientList : clientInfo:ClientInformation -&gt; Unit

[&lt;ServiceContract(
    Namespace = &quot;urn:WindowsAzurePlatformKit:Labs:AzureTalk:2009:10&quot;,
    CallbackContract = typeof&lt;IClientNotification&gt;,
    SessionMode = SessionMode.Required)&gt;]
type IChatService =

    [&lt;OperationContract(IsInitiating = true)&gt;]
    abstract Register : userName:string -&gt; ClientInformation

    [&lt;OperationContract(IsInitiating = false)&gt;]
    abstract SendMessage : message:string -&gt; sessionId:string -&gt; Unit

    [&lt;OperationContract(IsInitiating = false)&gt;]
    abstract GetConnectedClients : Unit -&gt; IEnumerable&lt;ClientInformation&gt;
</pre>
<p>The server:</p>
<pre class="brush: csharp;">
namespace WorkerRole1

open System
open System.Diagnostics
open System.Linq;
open System.Net;
open System.Threading
open Microsoft.WindowsAzure.Diagnostics
open Microsoft.WindowsAzure.ServiceRuntime
open System.Runtime.Serialization
open System.Collections.Generic
open System.ServiceModel
open AzureTalk.Contract

type internal SessionManager() =
    static let sessionLock = new ReaderWriterLockSlim()
    static let read (f:Unit-&gt;'a) =
        sessionLock.EnterReadLock()
        try
            f()
        finally
            sessionLock.ExitReadLock()
    static let write (f:Unit-&gt;'a) =
        sessionLock.EnterWriteLock()
        try
            f()
        finally
            sessionLock.ExitWriteLock()
    static let sessions = new Dictionary&lt;string, SessionInformation&gt;()

    static member TryGetSession(sessionId:string) =  read (fun() -&gt; sessions.TryGetValue(sessionId))

    static member CreateOrUpdateSession (sessionId:string) (userName:string) (roleId:string) (callback:IClientNotification option) =
        write (fun() -&gt;

                let (existingSession, session) = sessions.TryGetValue(sessionId)
                if (not existingSession) then
                    let session = SessionInformation(sessionId, userName, roleId, true, callback)
                    sessions.Add(sessionId, session)
                    (existingSession, session)
                else
                    session.SessionId &lt;- sessionId
                    session.UserName  &lt;- userName
                    session.RoleId    &lt;- roleId
                    session.Callback  &lt;- callback
                    session.IsActive  &lt;- true
                    (existingSession, session))

    static member RemoveSession (sessionId:string) =
        write (fun() -&gt;
                    let (exists,session) = sessions.TryGetValue(sessionId)
                    if (exists) then session.IsActive &lt;- false; sessions.Remove(sessionId) |&gt; ignore)

    static member GetActiveSessions() = (read (fun() -&gt; sessions.Values |&gt; Seq.filter (fun s -&gt; s.IsActive))).ToArray()

///Implementation of the WCF chat service
[&lt;ServiceBehavior(
    InstanceContextMode = InstanceContextMode.Single,
    ConcurrencyMode = ConcurrencyMode.Multiple,
#if DEBUG
    IncludeExceptionDetailInFaults = true,
#else
    IncludeExceptionDetailInFaults = false,
#endif
    AddressFilterMode = AddressFilterMode.Any)&gt;]
type ChatService() =
    let log message kind = Trace.WriteLine(message, kind)

    member this.NotifyConnectedClients (clientInfo:ClientInformation) =
        SessionManager.GetActiveSessions()
        |&gt; Array.iter (fun client -&gt;
            try
                match client.Callback with
                | Some(callback)-&gt; callback.UpdateClientList(clientInfo)
                | None -&gt; ()

            with
            | :? TimeoutException as e -&gt;
                log (sprintf &quot;Unable to notify client '%s'. The service operation timed out. '%s'&quot; client.UserName e.Message) &quot;Error&quot;
                //(box client :?&gt; ICommunicationObject).Abort()
                client.Callback &lt;- None

            | :? CommunicationException as e -&gt;
                log (sprintf &quot;Unable to notify client '%s'. There was a communication problem. '%s' - '%s'&quot; client.UserName e.Message e.StackTrace) &quot;Error&quot;
                //(box client :?&gt; ICommunicationObject).Abort()
                client.Callback &lt;- None)

    interface IClientNotification with

        member this.DeliverMessage message fromSessionId toSessionId =
            let (fromExists,fromSession)= SessionManager.TryGetSession(fromSessionId)
            let (toExists, toSession) = SessionManager.TryGetSession(toSessionId)
            if (fromExists &amp;&amp; toExists) then
                match toSession.Callback with
                | Some(callback) -&gt;
                    callback.DeliverMessage message fromSessionId toSessionId
                    log (sprintf &quot;Message '%s' send from '%s' to '%s'.&quot; message fromSession.UserName toSession.UserName) &quot;Information&quot;
                |  None -&gt; ()

        member this.UpdateClientList clientInfo =
            if clientInfo.IsActive
            then
                let (created, session) = SessionManager.CreateOrUpdateSession clientInfo.SessionId clientInfo.UserName clientInfo.RoleId None
                if created then log (sprintf &quot;Remote session '%s' by user '%s' has been opened in role '%s'.&quot; session.SessionId session.UserName session.RoleId) &quot;Information&quot;
            else
                SessionManager.RemoveSession(clientInfo.SessionId)
                log (sprintf &quot;Remote session '%s' by user '%s' has been opened in role '%s'.&quot; clientInfo.SessionId clientInfo.UserName clientInfo.RoleId) &quot;Information&quot;
            this.NotifyConnectedClients clientInfo

    interface IChatService with
        member this.Register userName =
            let roleId = RoleEnvironment.CurrentRoleInstance.Id
            let sessionId = OperationContext.Current.SessionId
            let callback = OperationContext.Current.GetCallbackChannel&lt;IClientNotification&gt;()

            let (existing, session) = SessionManager.CreateOrUpdateSession sessionId userName roleId (Some(callback))
            if (not existing)
                then
                    OperationContext.Current.Channel.Closed.Add(fun e -&gt;
                        SessionManager.RemoveSession sessionId
                        this.NotifyConnectedClients session
                        log  (sprintf &quot;Session '%s' by user '%s' has been closed in role '%s'.&quot; sessionId userName roleId)  &quot;Information&quot;)
                    log (sprintf &quot;Session '%s' by user '%s' has been opened in role '%s'.&quot; sessionId userName roleId) &quot;Information&quot;

            this.NotifyConnectedClients session
            ClientInformation(sessionId, userName, roleId)

        member this.SendMessage message sessionId =
            let fromSessionId = OperationContext.Current.SessionId
            (this :&gt; IClientNotification).DeliverMessage message fromSessionId sessionId

        member this.GetConnectedClients() =
            (SessionManager.GetActiveSessions()
            |&gt; Seq.map (fun session -&gt; ClientInformation(session.SessionId, session.UserName, session.RoleId)))

type WorkerRole() =
    inherit RoleEntryPoint()

    let log message kind = Trace.WriteLine(message, kind)

    let rec startChatService (retries:int) =
        if (retries = 0)
            then
                RoleEnvironment.RequestRecycle();
            else
                log &quot;Start chat service host...&quot; &quot;Information&quot;

                let serviceHost = new ServiceHost(typeof&lt;ChatService&gt;)

                serviceHost.Faulted.Add(fun e -&gt;
                    log (String.Format(&quot;Host fault occured. Aborting and restartign the host. Retry count: {0}&quot;, retries)) &quot;Error&quot;
                    serviceHost.Abort()
                    startChatService(retries - 1))

                let binding = new NetTcpBinding(SecurityMode.None)

                let externalEndPoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints.[&quot;ChatService&quot;]

                serviceHost.AddServiceEndpoint(typeof&lt;IChatService&gt;, binding, (String.Format(&quot;net.tcp://{0}/ChatService&quot;, externalEndPoint.IPEndpoint))) |&gt; ignore

                try
                    serviceHost.Open()
                    log &quot;Chat service host started successfully.&quot; &quot;Information&quot;
                with
                | :? TimeoutException as timeoutException -&gt; log (sprintf &quot;The service operation timed out. %s&quot; timeoutException.Message) &quot;Error&quot;
                | :? CommunicationException as communicationException -&gt; log (sprintf &quot;The service operation timed out.  %s&quot; communicationException.Message) &quot;Error&quot;

    override wr.Run() =

        log &quot;Worker Process entry point called&quot; &quot;Information&quot;

        startChatService 3

        while(true) do
            Thread.Sleep(300000)
            log &quot;Working&quot; &quot;Information&quot;

    override wr.OnStart() =

        // Set the maximum number of concurrent connections
        ServicePointManager.DefaultConnectionLimit &lt;- 12

        DiagnosticMonitor.Start(&quot;DiagnosticsConnectionString&quot;) |&gt; ignore

        // For information on handling configuration changes
        // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
        RoleEnvironment.Changing.Add(fun e -&gt;
            // If a configuration setting is changing
            if e.Changes |&gt; Seq.exists (fun change -&gt; change :? RoleEnvironmentConfigurationSettingChange) then
                // Set e.Cancel to true to restart this role instance
                e.Cancel &lt;- true)

        base.OnStart()
</pre>
<p>The client:</p>
<pre class="brush: csharp;">
module AzureClient.Client

open System
open System.Collections.Generic
open System.ServiceModel
open System.Runtime.Serialization
open System.Windows
open System.Threading
open AzureTalk.Contract

type IChatServiceChannel =
    interface IChatService
    interface IClientChannel

type ClientErrorEventArgs() =
    inherit EventArgs()

    let mutable message = &quot;&quot;
    let mutable cancel = false

    member this.Message with get() = message and set(x:string) = message &lt;- x
    member this.Cancel with get() = cancel and set(x:bool) = cancel &lt;- cancel

type ChatClient(callbackObject:IClientNotification,endpoint:string) as this =
    let binding = new NetTcpBinding(SecurityMode.None, false)
    let factory = new DuplexChannelFactory&lt;IChatServiceChannel&gt;(callbackObject, binding, endpoint)
    let error = new Event&lt;ChatClient*ClientErrorEventArgs&gt;()
    let onError message = error.Trigger(this, new ClientErrorEventArgs(Message = message, Cancel = false))

    let mutable _channel = None

    member this.Error = error.Publish

    member this.Channel
        with get() =
            let getChannel() =
                let channel = factory.CreateChannel()
                channel.Faulted.AddHandler(EventHandler(fun sender e -&gt;
                    channel.Abort()
                    _channel &lt;- None
                    System.Windows.MessageBox.Show(&quot;Channel Faulted&quot;) |&gt; ignore
                ))
                channel
            let channel =
                match _channel with
                | None -&gt; getChannel()
                | Some(x:IChatServiceChannel) when x.State = CommunicationState.Faulted -&gt; getChannel()
                | Some(x:IChatServiceChannel) -&gt; x
            _channel &lt;- Some(channel)
            channel

    member this.Close() =
        try
            match _channel with | None -&gt; () | Some(x:IChatServiceChannel) -&gt; x.Close()
        with
        | :? TimeoutException as e -&gt; this.Channel.Abort()
        | :? CommunicationException as e -&gt; this.Channel.Abort()

    interface IChatService with
        member this.Register userName = this.Channel.Register(userName)
        member this.SendMessage message toUserName = this.Channel.SendMessage message toUserName
        member this.GetConnectedClients() = this.Channel.GetConnectedClients()

type Client() as this =
    let mutable userList = Seq.empty&lt;ClientInformation&gt;
    let endpoint = &quot;net.tcp://localhost:3030/ChatService&quot;
    let chatClient = new ChatClient(this,endpoint)
    let context = SynchronizationContext()
    let sync(f:obj-&gt;unit) = context.Post(SendOrPostCallback(f), null)
    let showMsg msg = System.Windows.MessageBox.Show(msg) |&gt; ignore
    let showErr err = System.Windows.MessageBox.Show(err) |&gt; ignore
    do
        chatClient.Error.AddHandler(fun _ (_,ea) -&gt;  showMsg ea.Message)

    interface IClientNotification with
        member this.DeliverMessage message fromSessionId toSessionId =
            sync(fun state -&gt;
                match (userList |&gt; Seq.tryFind(fun userInfo -&gt; userInfo.SessionId = fromSessionId)) with
                | Some(fromSession) -&gt; showMsg (sprintf @&quot;Message: %s \n From: %s&quot; message fromSession.UserName)
                | None -&gt; showErr (sprintf &quot;A message was received from an unknown sender. The session ID '%s' is not registered.&quot; fromSessionId)
                )

        member this.UpdateClientList(session) =
            sync(fun state -&gt;
                match (userList |&gt; Seq.tryFind(fun userInfo -&gt; userInfo.SessionId = session.SessionId)) with
                | Some(client) -&gt;

                    if session.IsActive
                    then
                        client.UserName &lt;- session.UserName
                        client.RoleId &lt;- session.RoleId
                    else
                        userList &lt;- userList |&gt;  Seq.filter(fun u -&gt; u = client)
                        showMsg (sprintf &quot;User '%s' has left the chat.&quot; client.UserName)
                | None -&gt;
                    if session.IsActive
                    then
                        userList &lt;- Seq.append ([session] |&gt; List.toSeq) userList
                        showMsg (sprintf &quot;User '%s' has joined the chat.&quot; session.UserName)
                )
    member this.Register userName = chatClient.Channel.Register(userName)

    member this.SendMessage message toSessionId = chatClient.Channel.SendMessage message toSessionId

    member this.GetConnectedClients() = chatClient.Channel.GetConnectedClients()

let client = new Client()
let clientInformation = client.Register &quot;Matt&quot;

client.GetConnectedClients() |&gt; Seq.iter(fun c -&gt; client.SendMessage &quot;Hello from Matt&quot; c.SessionId)

Console.Read() |&gt; ignore
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.mattssoftwareblog.com/?feed=rss2&amp;p=219</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Collaborative Development Using F# Interactive</title>
		<link>http://www.mattssoftwareblog.com/?p=212</link>
		<comments>http://www.mattssoftwareblog.com/?p=212#comments</comments>
		<pubDate>Sat, 14 Nov 2009 02:01:28 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[F#]]></category>
		<category><![CDATA[FSI]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.mattssoftwareblog.com/?p=212</guid>
		<description><![CDATA[This is a proof of concept of an interactive collaborative development environment I built using  F# Interactive. The aim here is to explore different ideas for further development, not so much as to present an alternative to Visual Studio :) Source code here (zip).  &#8221;Make it pink&#8221; code (txt), and Space Scene code (txt).
The video [...]]]></description>
			<content:encoded><![CDATA[<p>This is a proof of concept of an interactive collaborative development environment I built using  F# Interactive. The aim here is to explore different ideas for further development, not so much as to present an alternative to Visual Studio :) Source code <a href="http://www.mattssoftwareblog.com/software/3DWPF/EchoDev.zip">here</a> (zip).  &#8221;Make it pink&#8221; <a href="http://www.mattssoftwareblog.com/software/3DWPF/Make%20it%20pink.txt">code </a>(txt), and Space Scene <a href="http://www.mattssoftwareblog.com/software/3DWPF/Space%20Scene.txt">code </a>(txt).</p>
<p>The video demonstrates a server and two clients collaborating on the same machine.</p>
<p style="text-align: center;">
<p style="text-align: center;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="344" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/9f0MnRYLU3I&amp;hl=en_US&amp;fs=1&amp;" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="425" height="344" src="http://www.youtube.com/v/9f0MnRYLU3I&amp;hl=en_US&amp;fs=1&amp;" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p style="text-align: center;">
<p style="text-align: left;">The way it works is that there are two different roles, the server (EchoServer) and the client (EchoClient). The role of the server is to act as repeater between the clients. When one client inputs source code the code is automatically sent to all the other clients. The server stores the code so when a new client joins it can be brought up to speed with all of the other clients.</p>
<p>This has the following advantages;</p>
<ul>
<li>Everyone is on the same page with the latest version of the software</li>
<li>All developers work with the very latest source code</li>
<li>The source code is continuously integrated in real time</li>
<li>‘Build’ breaks are noticed (and fixed) immediately</li>
</ul>
<p>There are also a number of disadvantages;</p>
<ul>
<li>Cannot undo certain operations with side effects</li>
<li>Code from the network is being downloaded and run on your machine</li>
<li>The entire source code is a stored as single string</li>
</ul>
<p>The reason I am playing with this is prepare for my next move into Domain Specific Modeling tools.</p>
<p>I’ve included the source code below. It is prototype code, so there are probably a few bugs in it, and as always feedback is greatly appreciated.</p>
<p><span id="more-212"></span></p>
<p>EchoServer</p>
<pre class="brush: csharp;">
#light

open System
open System.IO
open System.Text
open System.Net
open System.Net.Sockets
open System.Threading
open System.Diagnostics
open System.Runtime.Serialization;
open System.Runtime.Serialization.Formatters.Binary;

// Connection settings
// Arguments IP address, and Port number
// e.g. 127.0.0.1 9050
let IPaddr = IPAddress.Loopback
let PortNo = 9050
let mutable filename = &quot;log.txt&quot;

// Helper functions
let wrapEvent (fBlock:unit-&gt;'a) =
    let event = new Event&lt;'a&gt;()
    let eventThread = new Thread(fun () -&gt;  while true do event.Trigger((fBlock())))
    do eventThread.Start()
    event.Publish

let write s = printf &quot;%s\n&quot; s
let read() = System.Console.ReadLine()

// Networking functions
// types of messages, message error / disconnect = -1, connect = 0, command = 1
type Message = int * obj
type Client = string*(Message-&gt;unit)*(unit-&gt;Message)*NetworkStream

let mutable code = &quot;&quot;

let clients = new ResizeArray&lt;Client&gt;()

let getByteArray (o:obj) =
    use ms = new MemoryStream()
    let bf = new BinaryFormatter()
    bf.Serialize(ms,o)
    ms.ToArray()

let getObject (ba:byte array) =
    use ms = new MemoryStream(ba)
    let bf = new BinaryFormatter()
    ms.Position &lt;- int64 0;
    bf.Deserialize(ms)

let sendVarData (stream:NetworkStream) (data:byte array) =
    let datasize = BitConverter.GetBytes(int32 data.Length)
    stream.Write(datasize, 0, 4)
    stream.Write(data, 0, data.Length)
    stream.Flush()

// There has to be a much better way? :)
let receiveVarData (stream:NetworkStream) =
    let mutable total = 0
    let mutable recv = 0
    let datasize = [|for n in 0..4 -&gt; byte 0 |] // anyone have a better idea on how to do this?
    stream.Read(datasize, 0, 4) |&gt; ignore
    let size = BitConverter.ToInt32(datasize,0)
    let mutable dataleft = size;
    let mutable data = [|for n in 0..size -&gt; byte 0 |] // anyone have a better idea on how to do this?
    let mutable flag = false
    while total &lt; size &amp;&amp; not flag do
        recv &lt;- stream.Read(data, total, dataleft)
        if (recv = 0) then
            data &lt;- Encoding.ASCII.GetBytes(&quot;exit &quot;)
            flag &lt;- true
        total &lt;- total + recv
        dataleft &lt;- dataleft - recv
    data

let tcpListen ip portNo =
    try
        let tcp = new TcpListener(IPaddr, PortNo)
        tcp.Start()
        let conRecv = wrapEvent(fun () -&gt; tcp.AcceptTcpClient())
        write &quot;Awaiting connections&quot;
        conRecv
    with
    | e -&gt; write (&quot;Unable to create TcpListener &quot; + e.Message)
           exit 1

let server = tcpListen IPaddr PortNo

let clientHandler (client:TcpClient) =
    let ipaddr = client.Client.RemoteEndPoint.ToString()
    let ns = client.GetStream()
    let send(msg:Message) = try (sendVarData ns (getByteArray msg)) with | _ -&gt; ()
    let recv()  =  try (getObject (receiveVarData ns)) :?&gt; Message with | _ -&gt; (-1,null)
    clients.Add(ipaddr, send, recv, ns)
    write (&quot;New Connection from: &quot; + ipaddr)
    let recvMsg = wrapEvent (fun () -&gt;
        let (i,o) = recv()
        if i = -1 then
            clients.Remove(ipaddr,send,recv,ns) |&gt; ignore
            write (ipaddr.ToString() + &quot; has disconnected&quot;)
            Thread.CurrentThread.Abort()
        (i,o))
    recvMsg.Add(fun (msg) -&gt;
        let (i,o) = msg
        match i with
        | 0 -&gt; send(1,code + &quot;\n;;&quot;) // start msg received - send everything
        | 1 -&gt;
            write ((string o) + &quot;\n&quot;)
            let str = &quot;\n\n&quot; + string o
            code &lt;- code + str
            for (_,send,_,_)  in clients do send(1,o)  // echo command to all clients
        | _ -&gt; write &quot;Unhandled message received&quot;)

server.Add(fun (client) -&gt; clientHandler client)

let readUrl (url:string) =
    try
        use sr = new StreamReader(WebRequest.Create(url).GetResponse().GetResponseStream())
        code &lt;- sr.ReadToEnd()
        write (&quot;Loaded &quot; + url)
        // send uploaded code to clients
        for (_,send,_,_)  in clients do send(1,code)
    with
    | e -&gt; write (sprintf &quot;Unable to open url %s Error: %s&quot; url e.Message )
let readFile filename =
    if File.Exists filename then
        try
           code &lt;- File.ReadAllText(filename)
           write (&quot;Loaded &quot; + filename)
           // send uploaded code to clients
           for (_,send,_,_)  in clients do send(1,code)
        with
        | e -&gt; write (sprintf &quot;Unable to open file %s Error: %s&quot; filename e.Message )
    else write (&quot;File not found:&quot; + filename)
let writeFile filename =
    try
        File.WriteAllText(filename, code)
        write (&quot;Loading &quot; + filename)
    with
    | e -&gt; write (sprintf &quot;Unable to write to file %s Error: %s&quot;  filename  e.Message)
// Console
let inHandler cmd =
    match cmd with
    | &quot;reset&quot; -&gt;  code &lt;- &quot;&quot;; write &quot;Reseting code&quot;
    | (s:string) when (s.Split [|' '|]).[0] = &quot;load&quot; -&gt;
        let ss = s.Split [|' '|]
        match ss.Length with
        | 1 -&gt; readFile filename
        | 2 -&gt; readFile ss.[1]
        | _ -&gt; write &quot;Incorrect usage of the load command&quot;
    | (s:string) when (s.Split [|' '|]).[0] = &quot;loadUrl&quot; -&gt;
        let ss = s.Split [|' '|]
        match ss.Length with
        | 2 -&gt; readUrl ss.[1]
        | _ -&gt; write &quot;Incorrect usage of the loadUrl command&quot;
    | (s:string) when (s.Split [|' '|]).[0] = &quot;save&quot; -&gt;
        let ss = s.Split [|' '|]
        match ss.Length with
        | 1 -&gt; writeFile filename
        | 2 -&gt; writeFile ss.[1]
        | _ -&gt; write &quot;Incorrect usage of the save command&quot;
    | &quot;quit&quot; -&gt; exit 0
    | _ -&gt; write &quot;Command Not Found&quot;

let cnslReadLine = wrapEvent(fun () -&gt; System.Console.ReadLine())
cnslReadLine.Add(inHandler)

// Load up the space scene program
//readUrl &quot;http://www.mattssoftwareblog.com/software/3DWPF/SpaceScene.txt&quot;
</pre>
<p>EchoClient</p>
<pre class="brush: csharp;">
#light

open System
open System.IO
open System.Text
open System.Net
open System.Net.Sockets
open System.Threading
open System.Diagnostics
open System.Runtime.Serialization;
open System.Runtime.Serialization.Formatters.Binary;
open System.Windows
open System.Windows.Markup
open System.Windows.Controls
open System.Xaml
open System.Xml

// Connection settings
// Arguments IP address, and Port number
// e.g. 127.0.0.1 9050
let IPaddr = IPAddress.Loopback
let PortNo = 9050
let FSharpDir = @&quot;C:\Program Files (x86)\Microsoft F#\v4.0\&quot;

// Helper functions
let wrapEvent (fBlock:unit-&gt;'a) =
    let event = new Event&lt;'a&gt;()
    let eventThread = new Thread(fun () -&gt;  while true do event.Trigger((fBlock())))
    do eventThread.Start()
    event.Publish

let dispatch&lt;'T when 'T :&gt; Control&gt; (f:'T -&gt; Unit) (control:'T) =
    if (control.CheckAccess()) then f control
    else control.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background, Action (fun () -&gt; f(control))) |&gt; ignore

type ProcessShell(psi:ProcessStartInfo)  =
    let proc = Process.Start(psi)
    let outEvent = wrapEvent (fun () -&gt; proc.StandardOutput.ReadLine() + &quot;\n&quot;)
    let errEvent = wrapEvent (fun () -&gt; proc.StandardError.ReadLine() + &quot;\n&quot;)
    member this.Output = outEvent
    member this.Error = errEvent
    member this.Input(s:string) =
        proc.StandardInput.WriteLine(s)
        proc.StandardInput.Flush()

let psi() file wd args =
    let tmp = new ProcessStartInfo()
    tmp.UseShellExecute &lt;- false
    tmp.FileName &lt;- file
    tmp.WorkingDirectory &lt;- wd
    tmp.CreateNoWindow &lt;- true
    tmp.RedirectStandardError &lt;- true
    tmp.RedirectStandardInput &lt;- true
    tmp.RedirectStandardOutput &lt;- true
    tmp.Arguments &lt;- args
    tmp

// types of messages, message error / disconnect = -1, connect = 0, command = 1
type Message = int * obj

let write (s:string) = System.Console.WriteLine(s)
let read() = System.Console.ReadLine()

let connect(ip:IPAddress, p:int) =
    let getByteArray (o:obj) =
        use ms = new MemoryStream()
        let bf = new BinaryFormatter()
        bf.Serialize(ms,o)
        ms.ToArray()

    let getObject (ba:byte array) =
        use ms = new MemoryStream(ba)
        let bf = new BinaryFormatter()
        ms.Position &lt;- int64 0;
        bf.Deserialize(ms)

    let sendVarData (stream:NetworkStream) (data:byte array) =
        let datasize = BitConverter.GetBytes(int32 data.Length)
        stream.Write(datasize, 0, 4)
        stream.Write(data, 0, data.Length)
        stream.Flush()

    let receiveVarData (stream:NetworkStream) =
        let mutable total = 0
        let mutable recv = 0
        let datasize = [|for n in 0..4 -&gt; byte 0 |]
        stream.Read(datasize, 0, 4) |&gt; ignore
        let size = BitConverter.ToInt32(datasize,0)
        let mutable dataleft = size;
        let mutable data = [|for n in 0..size -&gt; byte 0 |]
        let mutable flag = false
        while total &lt; size &amp;&amp; not flag do
            recv &lt;- stream.Read(data, total, dataleft)
            if (recv = 0) then
                data &lt;- Encoding.ASCII.GetBytes(&quot;exit &quot;)
                flag &lt;- true
            total &lt;- total + recv
            dataleft &lt;- dataleft - recv
        data

    let tc = new TcpClient()
    tc.Connect(ip,p)
    let ns = tc.GetStream()
    let send(msg:Message) = try (sendVarData ns (getByteArray msg)) with | _ -&gt; ()
    let recv()  =  try (getObject (receiveVarData ns)) :?&gt; Message with | _ -&gt; (-1,null)
    (send, recv, ns)

// attempt connection
let (send:int*obj-&gt;unit , recv, stream) =
    try
        let tmp = connect(IPaddr, PortNo)
        tmp
    with
    | e -&gt;  write (sprintf &quot;Unable to connect to server %s, %i : %s&quot; (IPaddr.ToString()) PortNo  e.Message)
            exit 1

let parseXAML (xaml : string) =
    use ms = new MemoryStream(Encoding.ASCII.GetBytes(xaml))
    ms.Position &lt;- int64 0
    XamlReader.Load(ms)

let windowXaml =
    &quot;&lt;Window
        xmlns=\&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation\&quot;
        xmlns:x=\&quot;http://schemas.microsoft.com/winfx/2006/xaml\&quot;
        Title=\&quot;EchoClient\&quot; Height=\&quot;400\&quot; Width=\&quot;512\&quot;&gt;
    &lt;Window.Resources&gt;
        &lt;Style x:Key=\&quot;ConsoleTextBoxStyle\&quot; TargetType=\&quot;{x:Type TextBox}\&quot;&gt;
            &lt;Setter Property=\&quot;TextBox.Background\&quot; Value=\&quot;Black\&quot; /&gt;
            &lt;Setter Property=\&quot;TextBox.Foreground\&quot; Value=\&quot;White\&quot; /&gt;
            &lt;Setter Property=\&quot;TextBox.VerticalScrollBarVisibility\&quot; Value=\&quot;Auto\&quot; /&gt;
            &lt;Setter Property=\&quot;TextBox.TextWrapping\&quot; Value=\&quot;Wrap\&quot; /&gt;
            &lt;Setter Property=\&quot;TextBox.FontFamily\&quot; Value=\&quot;Lucida Console\&quot; /&gt;
            &lt;Setter Property=\&quot;TextBox.FontSize\&quot; Value=\&quot;10\&quot; /&gt;
        &lt;/Style&gt;
    &lt;/Window.Resources&gt;
    &lt;Grid&gt;
        &lt;Grid.RowDefinitions&gt;
            &lt;RowDefinition /&gt;
            &lt;RowDefinition Height=\&quot;4\&quot;/&gt;
            &lt;RowDefinition Height=\&quot;50\&quot;/&gt;
        &lt;/Grid.RowDefinitions&gt;
        &lt;TabControl Grid.Row=\&quot;0\&quot;&gt;
            &lt;TabItem Header=\&quot;Code\&quot;&gt;
                &lt;ScrollViewer&gt;
                    &lt;TextBox x:Name=\&quot;code_TextBox\&quot; IsReadOnly=\&quot;True\&quot; Style=\&quot;{StaticResource ConsoleTextBoxStyle}\&quot; /&gt;
                &lt;/ScrollViewer&gt;
            &lt;/TabItem&gt;
            &lt;TabItem Header=\&quot;Output\&quot;&gt;
                &lt;ScrollViewer&gt;
                    &lt;TextBox x:Name=\&quot;output_TextBox\&quot; IsReadOnly=\&quot;True\&quot; Style=\&quot;{StaticResource ConsoleTextBoxStyle}\&quot; /&gt;
                &lt;/ScrollViewer&gt;
            &lt;/TabItem&gt;
            &lt;TabItem Header=\&quot;Error\&quot;&gt;
                &lt;ScrollViewer&gt;
                    &lt;TextBox x:Name=\&quot;error_TextBox\&quot; IsReadOnly=\&quot;True\&quot; Style=\&quot;{StaticResource ConsoleTextBoxStyle}\&quot; /&gt;
                &lt;/ScrollViewer&gt;
            &lt;/TabItem&gt;
        &lt;/TabControl&gt;
        &lt;GridSplitter Grid.Row=\&quot;1\&quot; HorizontalAlignment=\&quot;Stretch\&quot; /&gt;
        &lt;DockPanel Grid.Row=\&quot;2\&quot;&gt;
            &lt;Button DockPanel.Dock=\&quot;Right\&quot; Name=\&quot;send_Button\&quot;&gt;_Send&lt;/Button&gt;
            &lt;ScrollViewer DockPanel.Dock=\&quot;Left\&quot; HorizontalScrollBarVisibility=\&quot;Auto\&quot; VerticalScrollBarVisibility=\&quot;Auto\&quot;&gt;
                &lt;TextBox x:Name=\&quot;inputCode_TextBox\&quot; Style=\&quot;{StaticResource ConsoleTextBoxStyle}\&quot; AcceptsReturn=\&quot;True\&quot;/&gt;
            &lt;/ScrollViewer&gt;
        &lt;/DockPanel&gt;
    &lt;/Grid&gt;
&lt;/Window&gt;&quot;

let window = windowXaml |&gt; parseXAML :?&gt; Window
let send_Button = window.FindName(&quot;send_Button&quot;) :?&gt; Button
let inputCode_TextBox = window.FindName(&quot;inputCode_TextBox&quot;) :?&gt; TextBox
let code_TextBox = window.FindName(&quot;code_TextBox&quot;) :?&gt; TextBox
let output_TextBox = window.FindName(&quot;output_TextBox&quot;) :?&gt; TextBox
let error_TextBox = window.FindName(&quot;error_TextBox&quot;) :?&gt; TextBox
send_Button.Click.Add(fun re -&gt; send(1,inputCode_TextBox.Text + &quot;\n;;&quot;))

// Close stream and console when window is closed
window.Closed.Add(fun _ -&gt; stream.Close(); exit 0)

// start up fsi
let fsi = ProcessShell((psi() (FSharpDir + &quot;fsi.exe&quot;) FSharpDir &quot;&quot;))
// Console out
fsi.Output.Add(fun (s) -&gt; write s)
fsi.Error.Add(fun (s) -&gt; write s)
// GUI out
fsi.Output.Add(fun (s) -&gt; output_TextBox |&gt; dispatch (fun output_TextBox -&gt; output_TextBox.Text &lt;- output_TextBox.Text + s))
fsi.Error.Add(fun (s) -&gt; error_TextBox |&gt; dispatch (fun error_TextBox -&gt; error_TextBox.Text &lt;- error_TextBox.Text + s))

// Callback incomming messages
let msgRecvEvnt = wrapEvent(fun () -&gt;
        let (i,o) = recv()
        if i = -1 then
            write &quot;Disconnected from server&quot;
            Thread.CurrentThread.Abort()
        (i,o))

// Console out, FSI in
msgRecvEvnt.Add(fun (i,o) -&gt; match i with | 1 -&gt;  fsi.Input (string o); write (string o) | _ -&gt; write &quot;Unrecognised message received&quot;)
// Gui out
msgRecvEvnt.Add(fun (i,o) -&gt;
                    match i with
                    | 1 -&gt; code_TextBox |&gt; dispatch (fun code_TextBox -&gt; code_TextBox.Text &lt;- code_TextBox.Text + (string o))
                    | _ -&gt; ())

// connect, and send IP address
send(0,IPaddr)

// run the application
let main() =
    let app = new Application()
    app.Run(window) |&gt; ignore

[&lt;STAThread&gt;]
do main()
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.mattssoftwareblog.com/?feed=rss2&amp;p=212</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Connecting to SQL Azure Using ADO.NET in F#</title>
		<link>http://www.mattssoftwareblog.com/?p=206</link>
		<comments>http://www.mattssoftwareblog.com/?p=206#comments</comments>
		<pubDate>Tue, 10 Nov 2009 04:51:50 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[F#]]></category>
		<category><![CDATA[SQL Azure]]></category>

		<guid isPermaLink="false">http://www.mattssoftwareblog.com/?p=206</guid>
		<description><![CDATA[This is a very straightforward port of SQL Azure code from msdn:


#r &#34;System.Core&#34;

open System
open System.Collections.Generic
open System.Linq
open System.Text
open System.Data.SqlClient
open System.Data

// Provide the following information
let userName = &#34;&#60;ProvideUserName&#62;&#34;
let password = &#34;&#60;ProvidePassword&#62;&#34;
let dataSource= &#34;&#60;ProvideServerName&#62;&#34;
let sampleDatabaseName = &#34;&#60;ProvideDatabaseName&#62;&#34;

let sendToCommand() (command:SqlCommand) query =
    command.CommandText &#60;- query
    command.ExecuteNonQuery()

// create the sample database
let createDatabase (command:SqlCommand) =
 [...]]]></description>
			<content:encoded><![CDATA[<p>This is a very straightforward port of SQL Azure code from <a href="http://msdn.microsoft.com/en-us/library/ee336243.aspx">msdn</a>:<br />
<span id="more-206"></span></p>
<pre class="brush: csharp;">
#r &quot;System.Core&quot;

open System
open System.Collections.Generic
open System.Linq
open System.Text
open System.Data.SqlClient
open System.Data

// Provide the following information
let userName = &quot;&lt;ProvideUserName&gt;&quot;
let password = &quot;&lt;ProvidePassword&gt;&quot;
let dataSource= &quot;&lt;ProvideServerName&gt;&quot;
let sampleDatabaseName = &quot;&lt;ProvideDatabaseName&gt;&quot;

let sendToCommand() (command:SqlCommand) query =
    command.CommandText &lt;- query
    command.ExecuteNonQuery()

// create the sample database
let createDatabase (command:SqlCommand) =
    (String.Format(&quot;CREATE DATABASE {0}&quot;, sampleDatabaseName)) |&gt; sendToCommand() command |&gt; ignore

// perform various operations
let modifyDatabase (command:SqlCommand) =
    let send() = sendToCommand() command
    // Create a table
    &quot;CREATE TABLE T1(Col1 int primary key, Col2 varchar(20))&quot; |&gt; send() |&gt; ignore

    // Insert sample records
    let rowsAdded = &quot;INSERT INTO T1 (col1, col2) values (1, 'string 1'), (2, 'string 2'), (3, 'string 3')&quot; |&gt; send()

    // Query the table and print the results
    let readCols() =
        command.CommandText &lt;- &quot;SELECT * FROM T1&quot;
        use reader = command.ExecuteReader()
        // Loop over the results
        while reader.Read() do
            Console.WriteLine(&quot;Col1: {0}, Col2: {1}&quot;, reader.[&quot;Col1&quot;].ToString().Trim(), reader.[&quot;Col2&quot;].ToString().Trim())

    // Query the table and print the results
    readCols()

    // Update a record
    &quot;UPDATE T1 SET Col2='string 1111' WHERE Col1=1&quot; |&gt; send() |&gt; ignore

    //Delete a record
    &quot;DELETE FROM T1 WHERE Col1=2&quot; |&gt; send() |&gt; ignore

    Console.WriteLine(&quot;\nAfter update/delete the table has these records...&quot;)

    // Query the table and print the results
    readCols()

let sqlBuild initialCatalog =
    new SqlConnectionStringBuilder(
         DataSource = dataSource,
         InitialCatalog = initialCatalog,
         Encrypt = true,
         TrustServerCertificate = false,
         UserID = userName,
         Password = password
    )

let runQuery stringBuilder func =
    use conn = new SqlConnection(stringBuilder.ToString())
    use command = conn.CreateCommand()
    conn.Open()
    func(command)
    conn.Close()

// Create a connection string for the master database, connect to the master database and create the sample database
createDatabase |&gt; (&quot;master&quot; |&gt; sqlBuild |&gt; runQuery)
// Create a connection string for the sample database, connect to the sample database and perform various operations
modifyDatabase |&gt; (sampleDatabaseName |&gt; sqlBuild |&gt; runQuery)
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.mattssoftwareblog.com/?feed=rss2&amp;p=206</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lessons learned in porting C# to F# (WPF)</title>
		<link>http://www.mattssoftwareblog.com/?p=200</link>
		<comments>http://www.mattssoftwareblog.com/?p=200#comments</comments>
		<pubDate>Mon, 09 Nov 2009 07:29:57 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[F#]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.mattssoftwareblog.com/?p=200</guid>
		<description><![CDATA[I encountered a ton of difficulties while porting code from C# to F#. Fortunately / unfortunately, so have many other people. Thankfully they took the time to write about these problems so my solutions were often only a quick search away. Here is a collection of some of the finds that were able to help [...]]]></description>
			<content:encoded><![CDATA[<p>I encountered a ton of difficulties while porting code from C# to F#. Fortunately / unfortunately, so have many other people. Thankfully they took the time to write about these problems so my solutions were often only a quick search away. Here is a collection of some of the finds that were able to help me in my endeavors.</p>
<p>I have done my best to attribute sources, and as always feedback is very much appreciated. Also, I will be updating my code viewer as soon as possible to stop it from embedding html smiley faces.</p>
<p><span id="more-200"></span></p>
<p><strong>1. Data Templates</strong></p>
<p>Unfortunately the only way to build Data Templates in code is being deprecated, which means we have to resort to writing Data Templates in XAML as a string. This string is then loaded using XamlReader as per the following code.</p>
<pre class="brush: csharp;">
let loadFromString xaml =
    use sr = new StringReader(xaml)
    use xr = XmlReader.Create(sr)
    XamlReader.Load xr
</pre>
<p>Steve Horsfeild has a good write up on this <a href="http://stevehorsfield.wordpress.com/2009/08/26/example-programmatic-addition-of-wpf-data-template/">here</a></p>
<p><strong>2. Attached Dependency Properties</strong></p>
<p>For ages I tried to  figure out why my attached properties were not showing up in the XAML intellisense. It turns out that I was missing the Get and Set functions for the property, as per below;</p>
<pre class="brush: csharp;">
    static let useHoverProperty =
                    DependencyProperty.RegisterAttached(
                     &quot;UseHover&quot;, typeof&lt;bool&gt;, typeof&lt;HoverInteractor&gt;)

    static member public SetUseHover(d:DependencyObject, _use:bool) = d.SetValue(useHoverProperty, _use)
    static member public GetUseHover(d:DependencyObject) = d.GetValue(useHoverProperty) :?&gt; bool
</pre>
<p><strong>3. Using options instead of Null</strong></p>
<p>I use this when a attribute is begin set at runtime and I know that no function will call the attribute until after it has been set. (from <a href="http://cs.hubfs.net/forums/thread/7729.aspx">here</a>)</p>
<p>&#8220;Nullable&#8221; member</p>
<pre class="brush: csharp;">
    static let mutable draggedElt = None

    static member private DraggedElt
        with get() = match draggedElt with | Some(v) -&gt; v | _ -&gt; failwith &quot;initialization fail&quot;
        and set(x:UIElement) = draggedElt &lt;- Some(x)
</pre>
<p>Check for &#8220;null&#8221;:</p>
<pre class="brush: csharp;">
match scrollOwner with
| Some(v) -&gt; v.InvalidateScrollInfo()
| None -&gt; ()
</pre>
<p>From <a href="http://cs.hubfs.net/forums/thread/7729.aspx">here</a></p>
<p><strong>4. Removing event handlers</strong></p>
<pre class="brush: csharp;">
let rec eventHandler = EventHandler(fun o e -&gt;

    // Hide the Viewport
    this.viewport.Visibility &lt;- Visibility.Hidden
    Panel.SetZIndex(this.backChildContainer, 0)

    // Show the FrontChild
    this.frontChildContainer.Visibility &lt;- Visibility.Visible
    dockAnim.Completed.RemoveHandler(eventHandler)
    )
</pre>
<p>However, sometimes you can&#8217;t keep a reference to the delegate instance. Fortunately you don&#8217;t have to. The following code works as the object passed into Remove() must match  the associated signature, but not necessarily the actual delegate instance you wish to remove. (Apress: Pro C# 2008 and the .Net 3.5 Platform)</p>
<pre class="brush: csharp;">
    override this.StartListening(source:obj) =
        let evtSource = source :?&gt; DataSource
        evtSource.DataChanged.AddHandler(Handler&lt;EventArgs&gt;(this.PrivateOnDataChanged))

    override this.StopListening(source:obj) =
        let evtSource = source :?&gt; DataSource
        evtSource.DataChanged.RemoveHandler(Handler&lt;EventArgs&gt;(this.PrivateOnDataChanged))
</pre>
<p><strong>4. Property changed events</strong></p>
<p>This is pretty straight forward (from <a href="http://www.voyce.com/index.php/2009/03/02/implementing-inotifypropertychanged-with-fsharp/">here</a>)</p>
<pre class="brush: csharp;">
let propertyChanged = Event&lt;_,_&gt;()
let notify obj s = propertyChanged.Trigger(obj, PropertyChangedEventArgs(s))

interface INotifyPropertyChanged with
    [&lt;CLIEvent&gt;]
    member this.PropertyChanged = propertyChanged.Publish
</pre>
<p><strong>6. Runtime casting: </strong></p>
<p>The following is the equivilent for using as (C# keyword), and then checking for Null. (from <a href="http://msdn.microsoft.com/en-us/library/dd233220(VS.100).aspx">here</a>)</p>
<pre class="brush: csharp;">
   match b1 with
   | :? Derived1 as derived1 -&gt; derived1.F()
   | _ -&gt; ()
</pre>
<p>Other bits and pieces;</p>
<ul>
<li>Accessing members in interfaces. It is a little odd but you have to cast the object to the interface type before you can call on the interface member: &#8220;(mark :&gt; CouchDBDocument).DocType&#8221; (from <a href="http://www.markhneedham.com/blog/2009/06/07/f-explicit-interface-implementation">here</a>)</li>
</ul>
<ul>
<li>Pass ‘by ref’ into a function can be done by using the prefix ‘&amp;” operator on a mutable (from <a href="http://www.sturmnet.org/blog/2008/05/16/oddities-in-fc-interaction">here</a>)</li>
</ul>
<pre class="brush: csharp;">
let mutable x = 1
if d.TryGetValue(&quot;foo&quot;, &amp;amp;x) then...
 </pre>
<ul>
<li>PropertyPath wouldn’t work with a string, it requires the actual property &#8220;PropertyPath(UIElement.OpacityProperty)&#8221;  (from <a href="http://jyliao.blogspot.com/2009/03/silverlight-with-f-background-thread.html">here</a>)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.mattssoftwareblog.com/?feed=rss2&amp;p=200</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Custom WPF Controls in F#</title>
		<link>http://www.mattssoftwareblog.com/?p=191</link>
		<comments>http://www.mattssoftwareblog.com/?p=191#comments</comments>
		<pubDate>Fri, 06 Nov 2009 01:14:57 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[F#]]></category>
		<category><![CDATA[HLSL]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[XAML]]></category>

		<guid isPermaLink="false">http://www.mattssoftwareblog.com/?p=191</guid>
		<description><![CDATA[*Update: Custom WPF Controls in F# is now available on Codeplex at http://wpffsharp.codeplex.com. You can still download the source from my site here. (Works best withVSTS2010 Beta1)
It is a translation of SAMS WPF Control Development Unleashed: Building Advanced User Interfaces written by Pavan Podila, and Kevin Hoffman to F#.  I picked this book for translation as it covers [...]]]></description>
			<content:encoded><![CDATA[<p>*Update: Custom WPF Controls in F# is now available on Codeplex at <a href="http://wpffsharp.codeplex.com">http://wpffsharp.codeplex.com</a>. You can still download the source from my site <a href="http://www.mattssoftwareblog.com/asdflkjh/BookExplorerFSharp.zip">here</a>. (Works best withVSTS2010 Beta1)</p>
<div id="attachment_197" class="wp-caption aligncenter" style="width: 310px"><img class="size-medium wp-image-197" title="BookExplorerWPFControlDevelopment" src="http://www.mattssoftwareblog.com/wp-content/uploads/2009/11/BookExplorerWPFControlDevelopment-300x211.PNG" alt="Screen Shot" width="300" height="211" /><p class="wp-caption-text">Screen Shot</p></div>
<p>It is a translation of <a href="http://www.informit.com/store/product.aspx?isbn=0672330334">SAMS WPF Control Development Unleashed: Building Advanced User Interfaces</a> written by Pavan Podila, and Kevin Hoffman to F#.  I picked this book for translation as it covers many advanced topics that other books shy away from.  I have been a reader of Pavan Podila’s blog <a href="http://blog.pixelingene.com/">Pixel in Gene</a> for some time, and I have also been waiting for a book dedicated advanced UIs, so when I heard that he was coming out with such a book I knew it was going to be exactly what I needed.</p>
<div class="wp-caption aligncenter" style="width: 170px"><img title="WPF Control Development" src="http://www.informit.com/ShowCover.aspx?isbn=0672330334&amp;type=f" alt="WPF Control Development Unleashed" width="160" height="209" /><p class="wp-caption-text">WPF Control Development</p></div>
<p>The aim behind this project is to serve as an extensive collection non trivial examples of WPF/F# UI. As I introduce people to F#, one thing I am constantly  asked is; can it do GUI. Now I can say yes, &#8230; well sort of. So far I have only translated 3,500 lines of F# code, and I am still not finished.</p>
<p>I’m doing this primarily as a learning experience and as a forcing function. I have already learned a lot about WPF and F#, and I plan on continuously improving the code as I learn more. Other contributions to the project would be very welcome, and if you spot mistakes or know of any better implementations please don’t hesitate to let me know.</p>
<p>I hope that you find this code to be useful to your WPF and F# projects , and happy coding.</p>
<p>-Matt</p>
<p>Read on for a list of known bugs;</p>
<p><span id="more-191"></span></p>
<p>A recent upgrade from VSTS 2010 Beta 1 to VSTS 2010 Beta 2 has unfortunately caused a whole lot of new  bugs (on top of the ones that were already there).</p>
<p>List of known bugs:</p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 616px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Chapter 2 &#8211; Media element doesn&#8217;t play</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 616px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Chapter 9  - TransitionContainer (delegate blocked off from TransitionTester_Loaded)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 616px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Chapter 10 &#8211; ComponentResourceKey ?? Not sure what is happening here</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 616px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Chapter 10 &#8211; Custom Chrome Window, no skin on window</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 616px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Chapter 11 &#8211; GardenViewPanel3D and Interactive GardenViewPanel3D both register the same names (they work individually)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 616px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Chapter 12 &#8211; Issues with enums for 3D mesh</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 616px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Chapter 13 &#8211; Dependency properties for SqueezeEffect and DisplacementEffect overlap? &#8220;Input&#8217; property was already registered by &#8216;DisplacementEffect&#8217;&#8221;</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 616px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Chapter 14 &#8211; WeekEvent / Command Source (Property SpikeControl.Command not found)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 616px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Chapter 15 &#8211; Media element doesn&#8217;t play</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 616px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Chapter 17 &#8211; Cannot find the static member &#8216;WatermakrTextProperty&#8217; on the type &#8216;TextBoxWatermarkHelper&#8217;</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 616px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">
<p>Chapter 18 &#8211; ComputedStartOffsetProperty on type RangeSelector</p>
</div>
<ul>
<li>Chapter 2 &#8211; Media element doesn&#8217;t play</li>
<li>Chapter 9  - TransitionContainer (delegate blocked off from TransitionTester_Loaded)</li>
<li>Chapter 10 &#8211; ComponentResourceKey ?? Not sure what is happening here</li>
<li>Chapter 10 &#8211; Custom Chrome Window, no skin on window</li>
<li>Chapter 11 &#8211; GardenViewPanel3D and Interactive GardenViewPanel3D both register the same names (they work individually)</li>
<li>Chapter 12 &#8211; Issues with enums for 3D mesh</li>
<li>Chapter 13 &#8211; Dependency properties for SqueezeEffect and DisplacementEffect overlap? &#8220;Input&#8217; property was already registered by &#8216;DisplacementEffect&#8217;&#8221;</li>
<li>Chapter 14 &#8211; WeekEvent / Command Source (Property SpikeControl.Command not found)</li>
<li>Chapter 15 &#8211; Media element doesn&#8217;t play</li>
<li>Chapter 17 &#8211; Cannot find the static member &#8216;WatermakrTextProperty&#8217; on the type &#8216;TextBoxWatermarkHelper&#8217;</li>
<li>Chapter 18 &#8211; ComputedStartOffsetProperty on type RangeSelector</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.mattssoftwareblog.com/?feed=rss2&amp;p=191</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Pretty Printing in F# interactive</title>
		<link>http://www.mattssoftwareblog.com/?p=177</link>
		<comments>http://www.mattssoftwareblog.com/?p=177#comments</comments>
		<pubDate>Thu, 15 Oct 2009 22:19:50 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[F#]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://www.mattssoftwareblog.com/?p=177</guid>
		<description><![CDATA[I’ve started playing around with XML in F# interactive and while F# is a joy to work with, the F# interactive sessions have two rather annoying and easily fixed deficiencies.

XML documents are printed out as a sequence of sequences
Printing out XML as text leaves it unformatted, i.e. the whole document is spread out on a [...]]]></description>
			<content:encoded><![CDATA[<p>I’ve started playing around with XML in F# interactive and while F# is a joy to work with, the F# interactive sessions have two rather annoying and easily fixed deficiencies.</p>
<ol>
<li>XML documents are printed out as a sequence of sequences</li>
<li>Printing out XML as text leaves it unformatted, i.e. the whole document is spread out on a single line</li>
</ol>
<p>To fix this I put together the following function;</p>
<pre class="brush: csharp;">#r &quot;System.Xml&quot;

open System.IO
open System.Xml
open System.Text

fsi.AddPrinter(fun (xml : System.Xml.XmlNode) -&gt;
    use ms = new MemoryStream()
    use w = new XmlTextWriter(ms, Encoding.Unicode)
    w.Formatting &lt;- Formatting.Indented
    xml.WriteContentTo(w)
    w.Flush()
    ms.Flush()
    ms.Position &lt;- int64 0
    use sr = new StreamReader(ms)
    sr.ReadToEnd())</pre>
<p>My initial expectation was that there would be a library function for nicely formatting XML. If there is and I haven’t found it, or if anyone knows of a better way to do this, please let me know.</p>
<p>Cheers,</p>
<p>Matt</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mattssoftwareblog.com/?feed=rss2&amp;p=177</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Domain Specific Modeling</title>
		<link>http://www.mattssoftwareblog.com/?p=131</link>
		<comments>http://www.mattssoftwareblog.com/?p=131#comments</comments>
		<pubDate>Sun, 19 Jul 2009 16:47:31 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[Uni projects]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[DSM]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.mattssoftwareblog.com/?p=131</guid>
		<description><![CDATA[This is an experiment in interactive user generated network graph layout. The video demonstrates the ability to specify a domain meta-model (class diagram) and then specify a model in the domain. The layout engine is force directed with a modified gradient decent algorithm for convergence.





Meta-model







Tsunami


]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal" style="text-align: left;">This is an experiment in interactive user generated network graph layout. The video demonstrates the ability to specify a domain meta-model (class diagram) and then specify a model in the domain. The layout engine is force directed with a modified gradient decent algorithm for convergence.</p>
<p class="MsoNormal" style="text-align: center;"><em><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="344" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="align" value="aligncenter" /><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/Kx4zfxPjoAc&amp;hl=en&amp;fs=1" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="425" height="344" src="http://www.youtube.com/v/Kx4zfxPjoAc&amp;hl=en&amp;fs=1" allowscriptaccess="always" allowfullscreen="true" align="aligncenter"></embed></object></em></p>
<p class="MsoNormal" style="text-align: center;">
<div class="mceTemp mceIEcenter" style="text-align: center;">
<dl id="attachment_132" class="wp-caption aligncenter" style="width: 310px;">
<dt class="wp-caption-dt"><a href="http://www.mattssoftwareblog.com/wp-content/uploads/2009/07/metamodel-data-structure.png" rel="shadowbox[post-131];player=img;"><img class="size-medium wp-image-132" title="metamodel-data-structure" src="http://www.mattssoftwareblog.com/wp-content/uploads/2009/07/metamodel-data-structure-300x242.png" alt="Graph &amp; Forces meta model" width="300" height="242" /></a></dt>
<dd class="wp-caption-dd">Meta-model</dd>
</dl>
</div>
<p class="MsoNormal" style="text-align: center;">
<p class="MsoNormal" style="text-align: center;">
<div class="mceTemp mceIEcenter" style="text-align: center;">
<dl id="attachment_136" class="wp-caption aligncenter" style="width: 310px;">
<dt class="wp-caption-dt"><a href="http://www.mattssoftwareblog.com/wp-content/uploads/2009/07/tsunami.png" rel="shadowbox[post-131];player=img;"><img class="size-medium wp-image-136" title="Tsunami" src="http://www.mattssoftwareblog.com/wp-content/uploads/2009/07/tsunami-300x207.png" alt="Tsunami" width="300" height="207" /></a></dt>
<dd class="wp-caption-dd" style="text-align: center;">Tsunami</dd>
</dl>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.mattssoftwareblog.com/?feed=rss2&amp;p=131</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
