Welcome to MSDN Blogs Sign in | Join | Help

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 | 2 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 | 2 Comments

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 | 3 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

CTP Awesomeness – Goto Definition

If you’ve used Visual Studio for a few years you’ve probably memorized all the shortcuts and methods for navigating source code. For example, if some XML looks unruly just press CTRL+K+D to automatically format the document. (If you’re interested in learning more Visual Studio tips, Sara Ford's blog is a must read.)

Anyway, I am happy to inform you that the F# CTP will have a much appreciated shortcut: Goto Definition. A feature written by an intern this summer, Kyle Ross.

So the next time you are in the bowels of some heinous F# code and what to know just what exactly that value you’re looking at, simply right click and select Goto Definition on the context menu. (Or you can press F12.)

Using Goto Defintion you can go from confusion …

clip_image002

… to clarification

clip_image004

Having used GotoDefintion since Kyle checked it in a few weeks ago, I really can’t imagine living without it. Check it out.

Posted by ChrSmith | 1 Comments
Filed under: ,

FSharpp to FSProj Converter

Wow, what a busy week!  The F# CTP is out the door, and it's already making reverberations around the blogospphere:

Don's Announcement
Units of Measure in F#: Part One, Introducing Units - HOTNESS
Downloading stock prices in F# - Part I - Data modeling
Welcome to the F# CTP project system: project templates
F# Scripts -- Zero to Execute in Ten Seconds 
F# Releases September CTP

I, unfortunately, am showing up late to the party since I've spent the last week kicking it old-school in Montana. Here's
a picture I snapped with my iPhone on Big Mountain in Whitefish.

iPhone 053

Anyways, never fear as I've have several blog posts queued up highlighting several parts of the F# CTP - which I'll try to release on a two-a-week schedule. This includes the final installment of "F# in 20 minutes", so stay tuned.

But this first post-CTP post will be devoted to a .fsharpp to .fsproj converter I wrote. While the new F# project system is awesome, it isn’t compatible with the old project system used in the MSR releases. The tool here will convert your old F# projects into the new format.

There are two modes of operation:

Convert a .fsharpp file
To convert an existing .fsharpp file, build the project and then run:
fsharpp2fsproj.exe <yourproject>.fsharpp

Convert an F# project built via command line
For more complex projects (typically built using a command line) you can convert a project based on the full command-line parameters passed to fsc.exe.

For example, if the project was built using:
fsc.exe file1.fs file2.fs -R Reference.dll -o MyProgram.exe

Save a file named "args.txt" with text "fsc.exe file1.fs file2.fs -R Reference.dll -o MyProgram.exe" and then run
fsharpp2fsproj.exe args.txt

Caveats:

  • It isn't perfect (read: you might find a bug)
  • It isn't supported (read: I might not fix your bug)
  • But if you do run into a problem let me know by sending mail to chrsmith at Microsoft.com or using the contact link on this blog.

I hope it is of use to you and definitely enjoy the F# CTP!

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 | 1 Comments
Filed under: , , ,

Attachment(s): FSharppToFSProj-v1.1.zip

Understanding Tail Recursion

You may have heard of Tail Recursion before, in fact, you may have even written tail recursive functions before without even knowing it. Even so, why should you care? Safety. Functional programming relies on recursive functions heavily since imperative looping structures are frowned upon. However, recursion chews up a valuable and limited resource – the stack – and can lead to an unrecoverable type of CLR error: the dreaded StackOverflow. Tail Recursion however is a form of recursion that doesn’t use any stack space, and thus is a way to use recursion safely.

Understanding tail recursion is crucial for writing efficient and safe functional code.

Understanding the Stack

A foundational concept in computer programming is the stack, which serves many uses, the most important of which is to know where to continue executing once you exit a function call.

Instruction Pointers and the Stack

Whenever you call a function the instruction pointer (address in the program code that identifies the next operation to execute) is pushed on the stack. Once the function returns a value, the stack is cleared and the instruction pointer is restored. Resuming the program in its previous state.

Consider this simple, recursive function for computing the factorial of a number.

clip_image001

If you set a breakpoint on the final recursion case you will see this callstack. Notice that each recursive call creates a new stack frame. Here you can clearly see the recursive function breaking the parameter x down into smaller and smaller values.

clip_image002

Stack Overflows

Simple enough. But remember that the stack is in a fixed block of memory, and genertaully limited to 1MB. So the factorial function will exhaust the stack for sufficiently large values.  An easier demonstration of this is this infinite loop function:

clip_image003

As soon as you execute this code, you run out of stack space and run into what is known as a stack overflow. Which means that there is no available memory on the stack to continue recusing. The CLR indicates this by throwing a StackOverflowException.

clip_image004

Tail recursion

Tail Call Optimization

Tail Recursion is a specialized type of recursion where there is a guarantee that nothing is left to execute in the function after a recursive call. In other words, the function returns the result of a recursive call.

If there is no additional instructions to execute, then there is no need to store the instruction pointer on the stack, since the only thing left to do once the recursive call exits is restore the stack. So rather than needlessly modifying the stack, tail calls use a GOTO statement for the recursion. And once the recursion eventually succeeds the function will return to the original instruction pointer location.

The previous implementation of factorial was not tail recursive because after the recursive call to factorial (x-1) completed, the function needed to multiply that result by x, the original parameter. This is made clearer if we rewrite the function like this:

let rec factorial x =
    if x <= 1 then 
        1
    else 
        // Recurse
        let resultOfRecusion = factorial (x - 1)
        // Instruction Pointer needed to be stored so we can resume
        // this function and execute these final two lines
        let result = x * resultOfRecusion
        result

Here is a tail recursive version. By passing the data around as an extra parameter we remove the need to execute code after the recursive function call, so no stack space is required. The result of the recursive call to 'tailRecursiveFactorial’ is the result of the function.

let factorial x =
    // Keep track of both x and an accumulator value (acc)
    let rec tailRecursiveFactorial x acc =
        if x <= 1 then 
            acc
        else 
            tailRecursiveFactorial (x - 1) (acc * x)
    tailRecursiveFactorial x 1

The compiled F# code, when viewed under Reflector and converted to C#, looks like this. Which is clearly not going to use up any stack space:

public static int tailRecursiveFactorial (int x, int acc)
{
    while (true)
    {
        int num = x;
        if (num <= 1)
        {
            return acc;
        }
        acc *= x;
        x--;
    }
}

If we fire up the Visual Studio debugger and set a breakpoint to when the tailRecursiveFactorial function eventually returns the accumulator, you see that only one stack frame has been used.

image

Again, to sum things up the benefits of using tail recursion are:

  • The function executes slightly faster, since no stack pushes and pops are required
  • The function can recurse indefinitely since no stack resources are used
  • No StackOverflow exceptions
Posted by ChrSmith | 4 Comments
Filed under: ,

Countdown to F# CTP

In case you didn’t see it over on Brian’s blog, he’s posted a sneak peak at the F# Project System: Part I Part II.

If you’ve used the Visual Studio integrate for our previous releases you might have noticed it was a tad ‘unsavory’. Well the images of the current bits speak for themselves.

And that’s just the tip of the ice berg. The CTP will feature:

  • A substantial improvement / cleanup of the F# libraries
  • An exciting new language feature previously unannounced…
  • MSBuild support
  • Intellisense improvements
  • And more

Hopefully you’re just as excited to get your hands on the new bits as we are to put them online.

Edit: Evidently I need to spend more time proof reading :P

Posted by ChrSmith | 10 Comments

ICFP Programming Contest

As far as elite programming contests go, I thought the only one around was the ACM-ICP. (The ACM International Collegiate Programming Contest.) However there is a less well known but arguably more hard core contest called the ICFP.

Each year as part of The International Conference on Functional Programming there is a programming contest in which the first prize is an official declaration that:

“The first place team's language is the programming language of choice for discriminating hackers”

Of course we all know the language of choice for discriminating hackers is F#, but if that could be proven by winning this completion then great! So Brian McNamara, Luke Hoban, Dustin Campbell, and Myself formed team Cup<’t>.

You can get the full ICFP 2008 problem description here, but generally it was write an AI for a Mars rover which avoids obstacles and blood thirsty Martians. I’ve never written a ‘real time’ app before and found the whole robotics domain pretty enjoyable. (Maybe you’ll start seeing blog posts using Robotics Developer Studio.)

Anyways, if you missed out on the competition I definitely encourage you to participate next year. We had a total blast.

Team Cup<'t> 

Pictured from left: Brian McNamara, Luke Hoban, Anson Horton, Alex Turner

Posted by ChrSmith | 3 Comments
Filed under:

Mastering F# Lists

Lists represent the backbone of functional programming and in order to be an effective F# programmer you must truly master list processing. Fortunately lists are simple and straight forward, so let’s begin.

Mastering F# Lists

There are several things which distinguish the F# list type from the .NET Arrays and generic List<T> type in the System.Collections.Generic namespace.

  F# List Arrays Generic List
Modify Elements No Yes Yes
Add New Elements No No Yes
Element Lookup O(n) slow O(1) fast O(1) fast

After looking at that chart, you might be wondering why even use F# lists at all? Element lookup is slow and you can’t even modify the thing once it has been created, so why bother. The reason why is that F# lists are immutable. Unlike arrays and generic lists, F# lists are guaranteed never to change once they have been created. If you have a type that returns an array or List<T> you don’t know what the outside world will do to it, check out Jomo’s Barrel of Bugs blog post for details.

But seriously, is this safety worth it? Yes. If used correctly in the right situations, F# lists can be more efficient than .NET Arrays or generic Lists. So let’s dig into looking at how F# lists work.

Linked Lists

F# lists are represented as linked lists, which are a foundational Computer Science data structure abstracted by links in a chain. Each individual link has a piece of data associated with it and may be connected to another link. The last link isn’t connected to anything, so it ‘points to null’ or the empty list []. (Ed. Sorry the empty list looks like a square block in my images.)

clip_image001[1]

There are two main operations on a list: Cons (adding a single element) and Concat (joining two lists).

Cons

Cons is where you add an element to the beginning of a list. In F# the type of the cons function’s type is:

‘a –> ‘a list –> ‘a list

The important thing to understand is that cons executes in constant, O(1), time. To join an element to an immutable linked list all you need to do is put that value in a list node and set its ‘next list node’ to be the first element in the existing list. Everything ‘after’ the new node is none the wiser.

clip_image002[1]

> 1 :: [2 .. 4];;

val it : int list = [1; 2; 3; 4]

Concat

Concat joins two lists together. The function type for concat is:

‘a list –> ‘a list' –> ‘a list

In order to join two lists all you need to do is set the ‘next node’ value in the last element of the first list equal to the first node in the second list. This sounds like a great solution, but remember you cannot modify list elements. So to join to lists you actually need to make a copy of the first list just so you can change what the last element points to. For this reason, execution of concat is on order O(n) where n is the number of elements in the first list. Visually you can see this by:

clip_image003[1]

To summarize: Cons is fast and easy and Concat is slowish.

List Module Functions

Now that we understand lists, let’s look at some built-in functions for manipulating them.

List.hd

List.hd returns the first element or head of a list.

List.tl

List.tl returns the ‘tail’ of the first element, of the list of items after the first element.

> let l = [1; 2; 3];;

val l : int list

> List.hd l;;

val it : int = 1

> List.tl l;;

val it : int list = [2; 3]

List.length

List.length returns the length of the list, nothing special to see here.

> List.length [1; 2; 3; 4; 5];;

val it : int = 5

List.rev

List.rev reverses a list. This makes a copy of the entire list so be careful when calling it, as it if you use List.rev in an inner loop your performance is hosed.

> List.rev [1 .. 10];;

val it : int list = [10; 9; 8; 7; 6; 5; 4; 3; 2; 1]

List.find

List.find takes a boolean function and returns the first element where that function returns true. However, if List.find doesn’t ‘find’ the element you are searching for it throws an exception. Since generally throwing exceptions is bad for everyone involved, I recommend List.tryfind instead, which returns an Option value. In this example we look through a list of numbers for one which is equal to the square root of 144.

> List.find (fun i -> i * i = 144) [1 .. 10];;

System.Collections.Generic.KeyNotFoundException: The item was not found in the collection

at Microsoft.FSharp.Core.Operators.not_found[T]()

at <StartupCode$FSI_0014>.$FSI_0014._main()

stopped due to error

> List.tryfind (fun i -> i * i = 144) [1 .. 10];;

val it : int option = None

List.filter

List.filter takes a function and produces a new list with only the items on which the function returned true. This filters down the list to just what you want. In the example we filter down a list of numbers to only those which are even.

> List.filter (fun i -> i % 2 = 0) [1 .. 20];;

val it : int list = [2; 4; 6; 8; 10; 12; 14; 16; 18; 20]

Aggregate Operators

The List module also supports a trio of aggregate operators: iter, map, and fold. These three functions provide all the power you need to do heavy lifting with any collection type. (In fact you will find a subset of iter, map, and fold in the Set, Seq, Option, and Array modules.)

List.Iter

The iter function is perhaps the simplest aggregate operator. All it does is iterates through each element in a list taking calling a function for each element. Note that the iter function doesn’t produce a value. Iterating through a list is predominately used for evaluating the side effects of the provided function, such as printing to the console.

> List.iter (fun i -> printfn "List contains %d" i) [1 .. 5];;

List contains 1

List contains 2

List contains 3

List contains 4

List contains 5

val it : unit = ()

List.Map

List.map is used to transform a list of items using a given function. The type of List.map is

(‘a –> ‘b) –> ‘a list –> ‘b list

Visually we can see the effects of a map using function f by:

clip_image004[1]

Inverting a list of numbers

Imagine we wanted to invert a list of numbers. All we need to do is map the invert function to each element in our list.

// Invert a list of numbers
let invertNumber x = x * -1

// Inverts numbers 1 through 10
let x = List.map invertNumber [1 .. 10]

// Prints: [-1; -2; -3; -4; -5; -6; ...]
printfn "%A" x

List.Fold

Folds are the most powerful aggregate operator and not surprisingly the most complicated. When you have a list of values and you want to distill it down to a single piece of data you use List.fold. List folds come in two flavors: fold_left and fold_right. The one you use determines the order in which elements are visited. (fold_left going left-to-right and fold_right going right-to-left.)

List.fold iterates through each element of the list and builds up an accumulator value. Once every element has been processed, List.fold returns the final value of the accumulator. The type of List.fold_left is:

(('a -> 'b -> 'a) -> 'a -> 'b list -> 'a)

To name the parameters fold_left takes:

List.fold_left :  ([function] accumulator listElement -> accumulator) initialAccumulatorValue theListToFold

List.Fold_left
Sum a list of numbers

The simplest example of a fold is summing a list of numbers. Our accumulator function will simply add the list element, x, to our accumulator value.

// Sum a list
let accumulate acc x = acc + x

let sumList = List.fold_left accumulate 0 [1 .. 10]

// Notice our accumulator function is identical to the (+) operator,
// so we can rewrite our fold as:
let conciseSum = List.fold_left (+) 0 [1 .. 10]

The accumulator value doesn’t need to be a primitive value though, perhaps you want to reduce a list to different pieces of data. You can have that accumulator be a tuple to store multiple values or even a record to store structured data.

Counting vowels

Before I go into the next example, let me quickly review an elegant syntax for cloning records:

// Cloning Records
type Car = { Make : string; Model : string; Year : int }

let eclipse   = { Make = "Mitsubishi"; Model = "Eclipse"; Year = 2005 }

// You could make a copy like this ...
let nextYears1 = { Make = eclipse.Make; Model = eclipse.Model; Year = 2006 }
// .. but an easier way would be this.
let nextYears2 = { eclipse with Year = 2006 }

Here’s another example of List.fold_left, totaling the number of vowels in a sentence. For our accumulator we will use a record.

// Counting vowels
type VowelCount = { A : int; E : int; I : int; O : int; U : int }

let countVowels acc c =
    match c with
    | 'a' -> { acc with A = acc.A + 1 }
    | 'e' -> { acc with E = acc.E + 1 }
    | 'i' -> { acc with I = acc.I + 1 }
    | 'o' -> { acc with O = acc.O + 1 }
    | 'u' -> { acc with U = acc.U + 1 }
    | _   -> acc
    
let listOfChars = Seq.to_list "The quick brown fox jumps over the lazy dog."

let accInitVal = { A = 0; E = 0; I = 0; O = 0; U = 0 }
// Evaluates to: {A = 1; E = 3; I = 1; O = 4; U = 2;} 

List.fold_left countVowels accInitVal listOfChars
Fold_right

Choosing between List.fold_left and List.fold_right may seem like a cosmetic difference, but folding order can have a substantial impact on performance. Consider the problem of splitting a string. Given a list of characters, return a list of lists of characters representing words separated by spaces.

// List.fold_left (bad)
let listOfChars2 = Seq.to_list "The quick brown fox jumps over the lazy dog"

let breakIntoWords (acc : char list list) c =
    // If the letter isn't a space, add it to our accumulator
    if c <> ' ' then
        // Words are stored in order, so the last word is at the end of the list...
        let revAcc = List.rev acc
        // Now get the first item in the reversed list
        let word = List.hd revAcc
        // And add this character at the end
        let updatedWord = word @ [ c ]
        // Finally put this updated word at the end of our accumulator
        let updatedRevAcc = updatedWord :: (List.tl revAcc)
        List.rev updatedRevAcc
    // If the letter is a space then add a new list of chars
    else 
        acc @ [ [] ]
        
let words = List.fold_left breakIntoWords [ [] ] listOfChars2

(* Prints:
[['T'; 'h'; 'e']; ['q'; 'u'; 'i'; 'c'; 'k']; ['b'; 'r'; 'o'; 'w'; 'n'];
 ['f'; 'o'; 'x']; ['j'; 'u'; 'm'; 'p'; 's']; ['o'; 'v'; 'e'; 'r'];
 ['t'; 'h'; 'e']; ['l'; 'a'; 'z'; 'y']; ['d'; 'o'; 'g']] *)
printfn "%A" words

The solution doesn’t seem terribly bad, we just need to deal with the inconvenience of reversing the lists and adding elements to the ‘back’. But remember that everything you call List.rev it takes O(n) time. And every type you call (@) that takes another O(n). In short, that fold was a steaming pile of slow. However, because of the nature of that problem if we go ‘backwards’ or fold in right-to-left order we can add characters and words to the front of the list, allowing us to use the much faster Cons function.

Solving this problem using List.fold_right allows us to remove all calls to List.rev and Concat. The resulting fold operation is much more performant.

// List.fold_right (good)
let listOfChars3 = Seq.to_list "The quick brown fox jumps over the lazy dog"

let breakIntoWordsGood c (acc : char list list) =
    // If the letter isn't a space, add it to our accumulator
    if c <> ' ' then
        // Words are stored in reverse order, so get the first word
        let word = List.hd acc
        // And add this character at the beginning
        let updatedWord = c :: word
        // Finally put this updated word at the beginning of our accumulator
        updatedWord :: (List.tl acc)
    // If the letter is a space then add a new list of chars
    else 
        [ [] ] @ acc
        
let words2 = List.fold_right breakIntoWordsGood listOfChars3 [ [] ] 

(* Prints:
[['T'; 'h'; 'e']; ['q'; 'u'; 'i'; 'c'; 'k']; ['b'; 'r'; 'o'; 'w'; 'n'];
 ['f'; 'o'; 'x']; ['j'; 'u'; 'm'; 'p'; 's']; ['o'; 'v'; 'e'; 'r'];
 ['t'; 'h'; 'e']; ['l'; 'a'; 'z'; 'y']; ['d'; 'o'; 'g']] *)
printfn "%A" words2

While there is still plenty more to know about lists, now you should be armed with enough knowledge to tackle Project Euler problems with ease.

In closing, I hope you enjoyed this post and if there is any F# topic you would like me to cover in the future blog post please use the Contact link and let me know. Thanks!

Posted by ChrSmith | 6 Comments
Filed under: ,

Some guidelines for readable F# code

When learning a new programming language it isn’t enough to know the syntax, you must also take the time to learn the idioms and styles for the language. Unfortunately those idioms and styles develop over years and F# still hasn’t had its ‘official v1'.0’ release. So where do we start?

We can begin by looking at F#'s roots - C# and OCaml - for guidance:

Once you start looking at those docs however, you'll begin to notice some conflicting advice. The problem isn't just that F# is both functional and object-oriented.  Good design guidelines are hard to pin down because F# can be used to write applications ranging from simple scripts to line-of-buisiness apps to physics simulations.

So I won't set out to write the ultimate set of coding guidelines for F#, but I will at the very least try to start the dialog.

For this post I would like to focus on readability. (Caveat Emptor, I completely reserve the right to flip-flop on any of these style issues; you have been warned.)

 

F# Don'ts

Let's start with the things you shouldn't do. If you want to write obfuscated F# code, here's the way to start.

Don't open Namespaces without a fully-qualified path

The semantics of open are that once you open a namespace, you can then open any nested namespaces without fully-qualifying them. If you do this however, you lose any ability to determine what 'open X' is actually referring too. Worse yet, you can run into namespace collisions. Recommendation: don't do this.

open System
open Collections
open Generic

// System.Collections.Generic.List<T>
let x = new List<string>()

Don't outscope values

In F# it is possible to introduce new values outscoping existing ones but since everything is immutable this doesn't modify the value, it simply creates a new one with the same name. To the novice F# developer, the following code would print both "Hello" and "Goodbye" however it does not.

let greet() =
    
    let message = "Hello"
    
    let printGreeting() = printfn "%s Bob" message
    
    // prints "Hello Bob"
    printGreeting()
    
    let message = "Goodbye"
    
    // prints "Hello Bob"
    printGreeting()

F# Code to Avoid

These aren't necessarily bad things, but you need to be careful when using these concepts.

Avoid mutable function values

Passing around a mutable function value enables some interesting functional programming patterns, but also enables new classes of bugs. You should avoid mutable function values unless they have a very limited scope.

let mutable mutableFunc = fun x y -> x + y

mutableFunc <- (fun x y -> x * y * -1)
mutableFunc <- (fun x y -> List.length [x .. y])
mutableFunc <- (fun x y -> (box x).ToString().Length + y)

mutableFunc 4 5

Avoid abusing type abbreviations

Type abbreviations simplify code and increase readability, but if you do it too much you are just introducing new types that need to be remembered by the person maintaining your code.

type string_string_dictionary = Dictionary<string, string>

Avoid abusing partial function application (currying)

Just like the previous bullet, currying is a great feature when used judiciously. Just be aware that at some point it is possible to go overboard and make your code impossible to debug.

let moveFunc x y = System.IO.File.Move(x, y)

let moveFileX = moveFunc @"D:\Documents\FileX.fs"

moveFileX "E:\NewFileLocation\FileX.fs"

F# Code to Consider

These are guidelines which may not always be applicable, but you should consider using them when the situation arises.

Prefer Sequence Expressions to Seq.unfold

There certainly is a place for Seq.unfold, but Sequence Expressions are much easier to read.

// Fibonacci numbers - 1, 1, 2, 3, 5, 8, 13, ...
let seq_unfold = 
    Seq.unfold 
        (fun (idx, last1, last2) -> 
            if idx >= 20 then 
                None 
            else 
                Some(last1 + last2, (idx + 1, last1 + last2, last1))) 
        (0, 0, 1)

// vs.

let sequence_expression =
    seq {
        let lastStep = ref (0, 1)
        for i in 1 .. 20 do
            let x, y = !lastStep
            yield x + y
            do lastStep := (x + y, x) }

 

F# Dos

These are things you should always do to aid readability of your F# programs.

Use the Pipe-Forward operator wherever possible

If you find yourself stringing together a lot of operations, don't write in the lame-imperative way. Use the pipe-forward operator to simplify the code. (Do this only within reason, since you can't store intermediate results long chains of piped functions are actually very hard to debug.)

let folderSize baseFolder =
    baseFolder
    |> filesUnderFolder
    |> Seq.map getFileInfo
    |> Seq.map getFileSize
    |> Seq.fold (+) 0L 
    |> convertBytesToMB

Add comments to Union Type data tags if necessary

Currently in F# you cannot name data associated with Union Type data tags, be sure to add a comment around the declaration site so that other programs know what the tag is expected to carry AND the order that data is expected to come in.

type MotorizedTransport =
    // Model, Year
    | SUV   of string * int
    // Model, Year, Carrying capacity
    | Truck of string * int * int 
Posted by ChrSmith | 1 Comments
More Posts Next page »
 
Page view tracker