3 Tips for More Elegant Let Bindings in F#
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
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:
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
height values which naturally belong together:
let width,height = 300,200
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:
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)
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!