Posted in:

Probably the first keyword you picked up if you have learned any F# is the let keyword – allowing you to bind identifiers to values or functions.

Here we bind hello to a string value and square to a function, and naughty to a mutable integer.

let hello = "hi"
let square x = x * x
let mutable naughty = 5

But the let keyword has a few addition tricks up its sleeve you might not be aware of if you’re an F# beginner. Here’s a few of my favourites:

Tuple Bindings

First of all, you can bind more than one value in a single statement very elegantly by using tuple pattern matching. A great use case would be for width and height values which naturally belong together:

let width,height = 300,200

in Bindings

Another handy trick which I stumbled across in this nice WAVE file generating snippet from Phil Trelford is to use the in keyword to allow you to bind a value to a name and then use it in the same expression.

Say we’re using a BinaryWriter and want to write an integer value to a file. We probably would want to avoid using magic numbers directly since it doesn’t help the reader know what the significance of the number is:

writer.Write(16)

We could change it to this to make the meaning of 16 more explicit, but at the cost of using two lines:

let headerSize = 16
writer.Write(headerSize)

However, with the in keyword we can keep our code all on one line, but nicely readable:

let headerSize = 16 in writer.Write(headerSize)

Fake Immutables

Sometimes in F# you’ll be creating instances of mutable objects from other .NET assemblies, and it always feels a shame to have to write code to construct an instance and then mutate it when you’re trying your best to stay immutable.

I ran into this a lot recently doing some WPF in F#. Often you create a framework element, and then set some properties like this:

let p = new Polyline()
p.Stroke <- Brushes.White 
p.StrokeThickness <- 2.0

If only there was a constructor that took those properties. Well, F# has a cool syntax that lets you pretend there is! Simply add them as named values in the new expression like this:

let p = new Polyline(Stroke = Brushes.White, StrokeThickness = 2.0)

Very nice, and lets you keep the naughty <- operator out of your nice pure functional code!