Welcome to MSDN Blogs Sign in | Join | Help

Speech Recognition is gun and easy!

Evidently Microsoft ninjaed a new assembly into the .NET framework with the 3.0 release called System.Speech.dll. If adding speech recognition or speech synthesis to your applications sounds like fun, read on.

Step 1: Train your computer

The first step for meaningful speech recognition is to tell your computer who is in charge. Open up the Control Panel, navigate to Ease of Access, Speech Recognition options, then select Training. The process of training will take about 10 minutes and is pretty tedious, but the results are well worth it. 

image

Step 2: Write some F# code

This is the easy part.

#light

open System
open System.Speech.Recognition

let sp = new SpeechRecognitionEngine()
let defaultDictationGrammar = new DictationGrammar()

defaultDictationGrammar.Name <- "Default Dictation"
defaultDictationGrammar.Enabled <- true

sp.LoadGrammar(defaultDictationGrammar)
sp.SetInputToDefaultAudioDevice()

sp.RecognizeAsync(RecognizeMode.Multiple)

sp.SpeechRecognized.Add(fun args -> printfn "Recognized [%f] '%s'" args.Result.Confidence args.Result.Text)

printfn ("(Just start talking. Press any key to quit.)")
Console.ReadKey(true) |> ignore

Step 3: Profit

Early results look promising, although it doesn't handle early 90's rap very well...

image

image

Posted by ChrSmith | 3 Comments
Filed under: , ,

F# No Longer Vaporware

REDMOND, WA - Sadly, after nearly four years of stringing developers along with Microsoft's longest touted non-product, F# was accidentally checked into the Visual Studio 2010 source tree Microsoft sources report. This mistake killed what would have been one of Microsoft's most popular vaporware project by giving it an actual release date.

The checkin was made by an intern, who was simply experimenting with his new Visual Studio Team Foundation Server enlistment. As a result of the checkin the F# compiler and project system will eventually ship with the next release of Visual Studio, Microsoft's premier development tool.

When asked about the event, senior researcher and language creator Don Syme lamented:

“It’s crazy. I mean, what do we do now - we can’t get it out. I was just working on F# as a way of getting out of all of those boring academic conferences. A way of looking busy for my boss. Then I come back from lunch Monday and the sucker was checked-in. This is a total ******* catastrophe.

I really don’t understand this place, you think we would have learned our lesson. You know those .NET Generics – same thing there too. Once Microsoft, always Microsoft – this place never changes.”

In fact, the entire F# team was shocked to hear the news. Developer Brian McNamara was quoted, “I didn’t sign on to work 80-hours a week only to have my code released to the world. This sucks, you mean to tell me that now people are going to actually use F#?”

clip_image002

Luke Hoban, program manager for the project was also troubled:

“Giving demos with this functional programming stuff is one thing; but an actual F# product is definitely another. If we ship it people will actually expect F# to be usable. You know, solve real world problems and stuff. This changes our whole strategy. When we were just demoing all we had to worry about was style. Substance on the other hand requires hard work.”

According to Hoban, most vaporware projects at Microsoft get terminated long before they build up much hype. F# was one of the company's most successful vaporware projects until last Monday. "We were able to keep up the illusion of shipping for so long by putting out CTP and beta releases. We probably could have probably shipped those things for another few years before people caught on that we never actually intended to ship F# in an officially supported release."

Below is an image the F# team was hoping to only mock up using PowerPoint and MSPaint. But after the source code accident, the screen shot is from an actual build of Visual Studio 2010.

F# in Dev10 

Currently the F# team in Redmond, Washington is scrambling to recover. Developer Jomo Fisher set up an emergency meeting with Senior Vice President S. Somasegar to discuss the potential ramifications of introducing .NET developers to functional programming.

The impact of this news is slowly being felt across the broader .NET developer community as well. Matthew Podwysoki, an avid F# blogger, was frustrated to hear the news:

“The bleeding edge of software has always been vaporware. Actually shipping F# in a box is so banal. How else am I supposed to impress people if not by saying that I know F#, a space-age programming language that you’ve never heard of.

If it becomes mainstream then I’ll probably have to learn something else. I mean, what’s next? People writing books for O'Reilly and putting flesh-eating demons on the cover? Come on.”

Not everybody reacted as emotionally to the news. Program manager Dustin Campbell tried to give perspective:

“Sometimes even the most promising projects ship. It happens. It is just part of software development. Either through good management, realistic schedules, or solid programmers some projects actually complete on time.

You just need to hope your next project will turn out better. If I were those F# guys, I’d be twice as lackadaisical in the planning of version 2.0.”

It may take weeks or even months for the team to cope with the unexpected realization that F# will eventually become a reality in Visual Studio 2010. In the mean time, you can protect yourself from productivity improvements induced by the language by avoiding any future Beta or CTP releases of Visual Studio 2010.

When Visual Studio 2010 is released, your best and only defense is to be prepared. Microsoft has began recommending that interested developers watch Luca Bolognese’s presentation titled An Introduction to Microsoft F#.

Check back here for more information on this story as it develops.

F# Zen - Array slices

Sorry for not being as regular with blogging, I've been sick and working hard on something pretty exciting. Don will post an announcement sooner or later.

Anyways, did you know that in F# you can easily take out a chunk of an array using an Array Slice? This is a simple syntax for selecting a subset of an array, which creates a new array copying the values. This slice syntax also works for 2D arrays as well in much the same way. (E.g., daysOfYear.[*, ..5])

Here are some simple examples:

open System
let daysOfWeek = Enum.GetNames( typeof<DayOfWeek> );;

// Standard array slice, elements 2 through 4
daysOfWeek.[2..4];;

// Just specify lower bound, elements 4 to the end
daysOfWeek.[4..];;

// Just specify an upper bound, elements 0 to 2
daysOfWeek.[..2];;

// Specify no bounds, get all elements (clones the array)
daysOfWeek.[*];;
Posted by ChrSmith | 2 Comments
Filed under:

F# Zen - ROT13

Below is a primitive implementation of ROT13 / Ceasar Cipher in F#. In short it is a simple encryption algorithm that works by 'shifting' each letter 13 places. So an 'a' becomes an 'n', a 'b' becomes an 'o', and so on. To decrypt the text you simply move 13 places in reverse.

We can do this in F# easily using function composition. Given a string, which is also a sequence of characters, we pass it to Array.of_seq so we have an array of characters. This will enable us to replace each character with its encrypted version. Next we map each character to our encryption function, which I'll go over next. Finally, we take our array of encrypted characters and return a new string.

To actually do the encryption, we will compose three functions together. int, will convert the character to its integer representation. "(+) 13" is a curried version of the (+) function, so it adds 13 to its argument. And then we compose that with the char function, which will convert the integer result to a character.

#light

(**
 * ROT13 in F#
 * 
 * 1. Convert the sequence of chars (string) to an array of chars
 * 2. For each character do the following:
 *    - Convert the character to an integer
 *    - Add 13 to the integer value of the character (by currying (+))
 *    - Convert the integer to a character
 * 3. Create a new string based off the encrypted characters
 *)
 
let EncryptText (text : string) = 
    text
    |> Array.of_seq
    |> Array.map (int >> ((+) 13) >> char)
    |> (fun chars -> new string(chars))

let DecryptText (text : string) = 
    text
    |> Array.of_seq
    |> Array.map (int >> ((+) -13) >> char)
    |> (fun chars -> new string(chars))

let Test message =
    let encrypted = EncryptText message
    let decrypted = DecryptText encrypted

    printfn "Original Message  = %s" message
    printfn "Encrypted Message = %s" encrypted
    printfn "Decrypted Message = %s" decrypted
    
Test "The quick fox jumped over the lazy dog"
Posted by ChrSmith | 10 Comments
Filed under: ,

F# Elevator Pitch

At the PDC I spent about eight hours a day for a full week answering the same question again and again: “What is F# and why should I use it.” While I would love to give a long and nuanced answer to this, in order to achieve a high throughput you need to resort to using the Elevator Pitch style.

The Pitch

So your boss comes to you and says your company is about to go bankrupt unless you write some application that will save the day. Having been told this time and time again you fire up Visual Studio and get to work.
The data access layer is trivial; you have code generators and UI tools to help out. The presentation layer is easy too – you have WYSIWYG designers. All you need to do them is wire these things together, which is straightforward in an object-oriented language. So from the get-go building the framework for your application is easy.

Your boss sees that your project is ‘mostly done’ and breathes a sigh of relief. He then starts stressing out about other things. But in reality, now is the time that the hard programming work begins. Conceptually you’re just putting the meat in your application – some business logic, implementing an algorithm, transforming some data. General computation. But this is really painful in C#.

Think about design patterns. They are actually really simple concepts, but require a complex web of types and interfaces to implement. This is because at heart everything in an OO language must be a class, so if you want to represent something simpler than that – a function, an algorithm, a piece of data – you have to build some OO hierarchy on top of it.

You could waste your time writing a lot of boiler plate code that has nothing to do with solving your problem, but fortunately there is a better way.

Instead of burning a week or two writing your functions and algorithms in terms of classes, you write your code in F#. F# is a new .NET programming language that approaches programming from an entirely different perspective. Abstracting algorithms, numeric computation, data analysis and exploration – all of these things are just easier in F#. Because that’s what the language is built to do.

So you write some part of your application in F# and shave weeks off your development time. And, because of the interoperability of the CLR, you can use it directly with your C# code and your boss/team is none the wiser. Your company is saved and you don’t have to work this weekend.

F# will make you extremely productive at algorithmic-level development (AKA programming in the small). So you can use F# where it makes sense and C# for everything else. F# is powerful new language for your tool belt.

Posted by ChrSmith | 6 Comments
Filed under: ,

PDC - Day 1

I'm writing this from the 'big room' in the LA Convention Center.If you don't know, PDC is a HUGE conference Microsoft holds to introduce cutting edge technology and show developers the roadmap for Microsoft's platforms. What that means for me, is that I've been talking about F# non-stop to anybody who will listen.

Random Notes:

  • Azure is some cool stuff. Previously you'd write some code and make cool apps, but if you wanted that to scale you'd have to rewrite everything from the ground up. If you plug into the Azure model, you write your app once and it can grow indefinitely. Bla bla bla future of computer bla bla bla the cloud.
  • I am trying to convince Alan Stevens to blog about F#. I was successful in blowing his mind with function composition.
  • I told the .NET Rocks guys that I was a "Long time, First Time". I don't think they got the joke.
  • I totally shook hands with Scott. Freaking. Hanselman.
  • The traffic in LA is really as bad as they say.
  • I also joined Twitter (aChrisSmith), which welcomed me with the following:

image

Anyways, if you're at PDC look for me - and don't miss out on Luca's F# talk on Thursday.

Posted by ChrSmith | 0 Comments
Filed under: ,

Due out Next Year – Programming F# by Chris Smith

I’d like to announce that for the past few months I’ve been secretly working on a book for O’Reilly titled Programming F#. My aim is to provide the one-stop-shop for learning the breadth of the F# language.

Squig_Oreilly

A special thanks goes out to Nate LaMartina, a friend of mine at Mythic Entertainment for putting together the book cover. I haven’t actually discussed the animal on the cover yet, but I’m sure the folks at O’Reilly media would love a flesh-eating Squig.

F# Zen – The Literal Attribute

 

When pattern matching it is easy to forget that you are capturing a new value instead of matching against an existing one. Take this function for example:

let E  = 2.718281828459
let PI = 3.141592653589

// Ooops - this captures a value
let isConstant x =
    match x with
    | PI
    | E -> true
    | _ -> false

The right way to write this code is to use the [<Literal>] attribute. This tells the F# compiler to treat this value as a constant literal which, among other things, enables it to be used with pattern matching.

[<Literal>]
let E  = 2.718281828459
[<Literal>]
let PI = 3.141592653589

// This matches against the literal value
let isConstant x =
    match x with
    | PI
    | E -> true
    | _ -> false
Posted by ChrSmith | 5 Comments
Filed under:

F# Zen - Colored printf

It’s easy to lose track of important data when logging output to the console window, fortunately you can use the System.Console.ConsoleColor property to set the output color. But unlike F#’s printfn, System.Console.WriteLine doesn’t use type inference and feels much different than the printf and printfn methods you’re used to.

Here’s how to create a version of printfn that takes a console color parameter.

#light

/// Colored printf
let cprintf c fmt = 

    Printf.kprintf 
        (fun s -> 
            let old = System.Console.ForegroundColor 
            try 
              System.Console.ForegroundColor <- c;
              System.Console.Write s
            finally
              System.Console.ForegroundColor <- old) 
        fmt
        
// Colored printfn
let cprintfn c fmt = 
    cprintf c fmt
    printfn ""

open System
cprintfn ConsoleColor.Blue  "Hello, World in BLUE!"
cprintfn ConsoleColor.Red   "... and in RED!"
cprintfn ConsoleColor.Green "... and in GREEN!"

let rotatingColors = 
    seq { 
        let i = ref 0
        let possibleColors = Enum.GetValues(typeof<ConsoleColor>)
        while true do
            yield (enum (!i) : ConsoleColor)
            i := (!i + 1) % possibleColors.Length
    }

"Experience the rainbow of possibility!"
|> Seq.zip rotatingColors
|> Seq.iter (fun (color, letter) -> cprintf color "%c" letter)

printfn ""
Console.WriteLine("(press any key to continue")
Console.ReadKey(true) |> ignore
Posted by ChrSmith | 1 Comments
Filed under:

F# Scripting Zen – Word Interop

Edit: Added a ‘comarg’ function to dramatically clean up the syntax for doing COM-interop, since F# will pass ‘ref types’ as byrefs to COM calls.

In a previous post I talked about how to take advantage of .FSX (F# Script) files to automate tasks for you. In this post I would like to share a script which I’ve found useful.

Let’s say you are working with a lot of Word documents, for example writing a book for O’Reilly on an upcoming .NET language. If you find revising your writing by hand easier than sitting in front of a computer, it would be helpful to have a script which prints out the book’s contents in such a way that doesn’t kill too many trees.

Here’s a simple F# script to automate the task of printing every Word doc in the same folder as the script. Simply copy the .FSX file into the desired folder, and whenever you want to print out all the documents right click and select ‘Run in F# Interactive…’.

Note how this takes advantage of F#’s support for optional parameters for COM-components.

#light

#I @"C:\Program Files\Microsoft Visual Studio 9.0\Visual Studio Tools for Office\PIA\Office12\"
#r "Office.dll"
#r "stdole.dll"
#r "Microsoft.Office.Interop.Word.dll"

open Microsoft.Office.Interop.Word

let private m_word : ApplicationClass option ref = ref None

let OpenWord()        = m_word := Some(new ApplicationClass())
let GetWordInstance() = Option.get !m_word
let CloseWord()       = (GetWordInstance()).Quit()

let comarg x = ref (box x)
   
let OpenDocument filePath = 
    printfn "Opening %s..." filePath
    
    word.Documents.Open(comarg filePath)

let PrintDocument (doc : Document) =
    
    printfn "Printing %s..." doc.Name

    doc.PrintOut(
        Background  = comarg true, 
        Range       = comarg WdPrintOutRange.wdPrintAllDocument,
        Copies      = comarg 1, 
        PageType    = comarg WdPrintOutPages.wdPrintAllPages,
        PrintToFile = comarg false,
        Collate     = comarg true, 
        ManualDuplexPrint = comarg false,    
        PrintZoomColumn = comarg 2,             // Pages 'across'
        PrintZoomRow    = comarg 2)             // Pages 'up down'

let CloseDocument (doc : Document) =
    printfn "Closing %s..." doc.Name
    doc.Close(SaveChanges = comarg false)

// -------------------------------------------------------------

let currentFolder = __SOURCE_DIRECTORY__

open System
open System.IO

try
    OpenWord()

    printfn "Printing all files in [%s]..." currentFolder

    Directory.GetFiles(currentFolder, "*.docx")
    |> Array.iter 
        (fun filePath -> 
            let doc = OpenDocument filePath
            PrintDocument doc
            CloseDocument doc)
finally
    CloseWord()

printfn "Press any key..."
Console.ReadKey(true) |> ignore

Disclaimer: Note that this post is provided ‘AS IS’ and offers no warranty and confers no rights. If this script file causes you bad mojo, seek a shaman for help and don’t blame me.

Posted by ChrSmith | 3 Comments
Filed under: ,

Shameless Plug Roundup

This post is entirely devoted to shameless plugs and ‘Me Too’ blogging.

 

The Stack Overflow public beta is out!

I’m trying to get the specialized badge, so ask some F# questions for me.

 

Amanda Laucher and Ted “Some Guy” Neward on .NET Rocks

The conversion got a little off topic, but I think Ted and Amanda held their ground well.

 

I’m totally just gave giving a talk titled Functional Programming with F# for the Northwest C++ Users Group tomorrow tonight, 9/17.

I’ll post a writeup with the talk’s content later. (Note to self, publish blog posts sooner.)

 

There is a cool blog on F# for Game Development which looks promising.

Jomo Fisher wrote a follow up to post 7 on how to improve perf by 100%

Posted by ChrSmith | 1 Comments
Filed under: ,

Book Review – F# for Scientists

A few weeks ago Dr. Jon Harrop published F# for Scientists and I had the fortune of snagging a copy at work. In short, it is an excellent book and an invaluable resource for those working in quantitative computing.

The best feature of the book is its conciseness and clarity. Given F#’s immense multi-paradigm nature it is impossible to cover everything in only 300 pages, so the book skips object-oriented programming and doesn’t do a thorough job covering F# syntax. Rather, the book covers just enough F# to solve scientific problems using the functional style. (And highlights just how well suited for science F# truly is!)

This focus on scientific computing however is also the book’s main (potential) flaw. If you consider yourself a scientist, then this book will teach you everything you need to know about F#. But if you are a .NET developer looking to integrate F# into your projects, you might find the book’s coverage of the language a little lacking. (Specifically in how to do object-oriented programming in F#.)

What impressed me most was just how clear the examples were. I haven’t had a lot of functional programming experience before working on F#, and I found the examples in the book to be very instructive on how to write ‘good’ functional code.

For example, an interview question I sometimes ask is to write the power set of a list in C#. There was a implementation of this in the book and I was floored to see it so concisely written.

let rec powerset = 
    function
    | []     -> [ [] ]
    | h :: t ->
        [ for subset in powerset t do
            yield! [subset; h :: subset] ]
> powerset [1; 2; 3];;
val it : int list list
= [[]; [1]; [2]; [1; 2]; [3]; [1; 3]; [2; 3]; [1; 2; 3]]

After reading the book I feel a inspired to use F# for more scientific-type applications.

If you are looking for a comprehensive overview of the F# language, this book isn’t it. But if you are at all interested in using F# for science I absolutely recommending it.

Edit: Evidently the super-elegant powerset implementation could be even more elegant. Does that make it super-duper-elegant?

Posted by ChrSmith | 4 Comments

Scripting in F#

The thing you hear most about F# is that it is multi-paradigm, meaning that you can use it to code in multiple styles of programming. But F# spans multiple-domains too. F# is not only well suited for quantitative computing, but it is surprisingly well suited for scripting as well.

The Desktop Scripting Scenario

The use-case for scripting is that you want to automate some task but don’t feel like resorting to writing a full-blown application to do it for you. For example, on the test team we use Visual Studio Team Test edition to gather Code Coverage for the F# product. In order to get our bits ready for code coverage I need to do the following:

  • Un-GAC the assembly
  • Instrument it using a filter
  • Disable strong name verification
  • GAC it
  • Delete NGEN images
  • NGEN it
  • [Run tests]
  • Un-GAC the instrumented binary
  • Delete NGEN images

Those steps are tedious as-is, let alone when you want to repeat the process for 10 different binaries!

Now I could write some wizard-style application to manage the general task of instrumenting assemblies and setting up the machine, but now I need to worry about source control, versioning, and installing this new app. Pffft whatevs.

Instead to solve this problem I’ve written an F# Script File (.fsx), which is an entire F# Project rolled into one file.

Note: Before you get excited and remind me that Windows PowerShell exists, I’ll just say the only thing better than learning a new programming language AND a new shell language, is just learning a new programming language.

So what exactly is an F# script file?

An F# script file is a normal F# source code file, except that .fsx files have a few extra capabilities.

Windows Explorer Integration

Double-Clicking on a .fsx file opens it up in Visual Studio. This gives you intellisense for editing. And the ability to highlight some code and run in F# Interactive for Visual Studio.

Right-Clicking on it has the context menu in Explorer shows an ‘Run with F# Interactive’ action which will execute the script directly through FSI.

clip_image002

Extra perks of F# Scripts

F# script files also have extra features available to them to compensate for not having project support. Again, think of .FSX files as a single-file project.

Adding Reference Via Code

When editing an F# Project in Visual Studio, to reference a separate assembly you can add a project reference through the UI. In F# scripts however you can just type #r and load an assembly. By default it will pick things out of the current directory and/or search paths (see below). (This was always allowed in previous releases of F#, but in the CTP this is only available to .fsx script files.)

#r "System.Core.dll"

open System.Collections.Generic

let hs = new HashSet<int>()

Add Directories to the Search Path

#r Will get things out of the GAC, but fully qualifying reference paths is a pain. You can use #I however to add a ‘search path’ to indicate where to look for references.

#I @"C:\Program Files (x86)\Reference Assemblies\Microsoft\VSTO\v9.0"

#r "Microsoft.Office.Tools.Common.v9.0.dll"

#r "Microsoft.Office.Tools.Excel.v9.0.dll"

Load Other Source Files

When I said F# Script files were one-file projects, I slightly lied. By using #load you can load additional source files into the script. This way you can reuse library-type code. Note that this is not recommended as a way for breaking up large scripts. If your script is too large for one file, you should consider creating an actual F# project.

#load "HelperLibrary.fs"

let x = HelperLibrary.SomethingAwesome()

Script Snippets

For building your own F# scripts, here are some simple building blocks to start from:

/// Get all files under a given folder
open System.IO

let rec allFilesUnder baseFolder = 
    seq {
        yield! Directory.GetFiles(baseFolder)
        for subDir in Directory.GetDirectories(baseFolder) do
            yield! allFilesUnder subDir 
        }
    
/// Active Pattern for determining file extension
let (|EndsWith|_|) extension (file : string) = 
    if file.EndsWith(extension) 
    then Some() 
    else None

/// Shell executing a program
open System.Diagnostics

let shellExecute program args =
    let startInfo = new ProcessStartInfo()
    startInfo.FileName <- program
    startInfo.Arguments <- args
    startInfo.UseShellExecute <- true

    let proc = Process.Start(startInfo)
    proc.WaitForExit()
    ()

Example F# Script

Putting the code above together yields a script for opening up each .fs or .fsi file under the script folder in Notepad. Not bad for six lines of code, and with some work you could even clean it up further taking advantage of Language Oriented Programming techniques…

// Launches all .fs and .fsi files under the current folder in Notepad
open System

allFilesUnder Environment.CurrentDirectory
|> Seq.filter (function 
            | EndsWith ".fs" _
            | EndsWith ".fsi" _
                -> true
            | _ -> false)
|> Seq.iter (shellExecute "Notepad.exe")

 

I’ve found F# scripts to be useful in my work. I’d love to hear from you about what sorts of applications you use FSX files for.

Posted by ChrSmith | 3 Comments
Filed under:

MSBuild tasks for Lex and Yacc

While I am thrilled about all the new features we've put into the F# CTP, perhaps the thing I'm most excited about are the MSBuild tasks for Lex and Yacc. You heard that right. If you want to use fslex.exe of fsyacc.exe as part of your project, you can now integrate them into your project via MSBuild. And the thing that makes this feature even better is the fact that I wrote the build tasks. (That’s right, testers do write features at Microsoft HUZZAH!)

To wire in fslex and fsyacc files, simply add the following snippet to your .FSPROJ file:

  <!-- Generate the lexer and parser -->
  <ItemGroup>
    <FsYacc Include="Parser.fsy" />
    <FsLex Include="Lexer.fsl" />
  </ItemGroup>

 

And import the F# PowerPack targets file.

<Import Project="$(MSBuildExtensionsPath)\FSharp\1.0\FSharp.PowerPack.Targets" />

And auto-magically Lex and Yacc will be kicked off as part of your build. Even better, is that since they are integrated into MSBuild the files won’t be regenerated unless the lexer or parser has changed. Which for sufficiently advanced parsers is a dramatic time savings.

To demonstrate this I’ve updated my MegaCalc project to the new F# Project System. Which if you recall is a simple four-function calculator written in F#.

clip_image002

Disclaimer: All code samples are provided "AS IS" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose. So in other words, if the attached source files cause you any grief whatsoever you can’t blame me or Microsoft.

Posted by ChrSmith | 4 Comments
Filed under: , , ,

Attachment(s): MegaCalc-v1.0.zip

Simple F# Game using WPF

 

With the F# CTP out the door, let’s take a look at what it can do.

Ryan Cavanaugh, not the famous Banjo Player, the one on the VS Pro Tools Team, helped me put together an artillery game called BurnedLand. (Kudos if you can catch the subtle reference.)  To play the game you adjust the Power, Angle, and Mass of your cannon ball so that when you fire it will (hopefully) hit the red tank.

clip_image001

In this post I’d like to highlight how this project takes advantage of:

  • The F# Project System
  • Units of Measure
  • WPF and data binding

The F# Project System

Rather than lumping all the code together into a single project, I separated out the game logic into an F# library and left all the UI in a C# WPF application. Since the F# Project System now supports project-to-project references, this all ‘just works’ like you would expect. If you tried multi-project development in the previous MSR Research releases, you know just what a pain this used to be.

Also, check out the sexy new F# icons!

clip_image002

Units of Measure

For calculating the cannon ball’s trajectory, you have to factor in gravity, velocity, position, time, etc. Using Units of Measure ensures that logic errors are caught at compile time by double-checking your math. (Check out Andrew’s blog for more info.)

clip_image003

Here’s a simpler example. Notice that multiplying a value with unit <m/s^2> by <s> * <s> results in a value with unit <m>.

clip_image004

Windows Presentation Foundation

One of the best features of WPF is databinding. Rather than programmatically updating UI elements whenever a value changes in the game logic module, you can use WPF data binding and the UI will always be in sync with no manual intervention.

For example, the game logic module in F# adds three simple properties for describing aspects of the Wind.

// ----- Wind -----
member this.Wind with get   = m_wind
                 and  set x = m_wind <- x
                              m_PropertyChanged.Trigger(this, new PropertyChangedEventArgs("Wind"))
                              m_PropertyChanged.Trigger(this, new PropertyChangedEventArgs("WindSpeed"))
                              m_PropertyChanged.Trigger(this, new PropertyChangedEventArgs("WindAngle"))

member this.WindAngle = Math.Atan2(float this.Wind.Y, float this.Wind.X) * (180.0 / Math.PI) 
   
member this.WindSpeed = String.Format("{0:0.0} m/s", this.Wind.Length)

 

By using data binding in WPF, the values are automatically up to date. In fact, if the Wind property ever changes, the UI elements will be updated via the PropertyChanged event in the game logic class.

                    <!-- Wind indicator -->
                    <Grid Width="{Binding DefaultBounds.Width}">
                        <Border Width="60" Height="60" BorderBrush="White" CornerRadius="60" RenderTransformOrigin="0.5,0.5">
                            <TextBlock Text="-->>>" HorizontalAlignment="Right" VerticalAlignment="Center"
                                       FontSize="6"
                                       Foreground="White" Margin="-8" />
                            <Border.RenderTransform>
                                <RotateTransform Angle="{Binding WindAngle}" />
                            </Border.RenderTransform>
                        </Border>
                        <TextBlock Text="{Binding WindSpeed}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" />
                    </Grid>

 

So the WPF value "{Binding WindSpeed}" is really a call to the F# code.

Disclaimer: All code samples are provided "AS IS" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose. So in other words, if the attached source files cause you any grief whatsoever you can’t blame me or Microsoft.

Posted by ChrSmith | 5 Comments
Filed under: ,

Attachment(s): BurnedLand-v1.0.zip
More Posts Next page »
 
Page view tracker