Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Tagged as

F#4 : Let / Use / Do Bindings

, 3 Mar 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
In this post we will look at F# bindings, in particular we will look at Let / Use / Do. Now you may be asking yourself what a binding is, and since we have not really covered it yet, now would be a good time to talk about this. Quite simply a binding associates an […]

In this post we will look at F# bindings, in particular we will look at Let / Use / Do. Now you may be asking yourself what a binding is, and since we have not really covered it yet, now would be a good time to talk about this.

Quite simply a binding associates an identifier with a value or function.

Let

You use the let keyword to bind a name to a value or function. There are actually subtlety different uses of Let, where one is declared as a top level in a module, and then another is where we define some sort of local context. Here is an example of both of these:

module DemoModule =

    let someFunction =
        let a = 1
        let b = 2
        a * b

We would be able to access the someFunction using a fully qualified name such as DemoModule.someFunction, but the nested Let bindings (a,b) are only accessible to the top level Let binding. You would typically see more cases where we are using the Let binding to declare some inner module values, so lets concentrate our efforts there (though it is still important to know you can use Let at module level).

So let’s have a look at a few more examples

let aString ="this is a string"
let aInt = 12
let aDecimal = 12.444
let aPiFunction () = Math.PI
let aSquareRootFunction (x) = Math.Sqrt(x)
let aFullyTypedSquareRootFunction (x :float) = Math.Sqrt(x)
let a,b = "a","tuple"

It can be seen that we are able to use the Let binding, to bind to numerous values, that can be of various types such as:

  • Integer
  • Decimal
  • A Function with no input parameters
  • A Function with input parameters (where the F# type inference system will correctly choose the Type)
  • A Function which has fully qualified parameter types
  • A tuple (a tuple of String * String in this case)

Another place you may see a Let binding is in a class, but we will cover this in more detail in a later article in this series

You can read more about the Let binding using MSDN : http://msdn.microsoft.com/en-us/library/dd233238.aspx

Use

The Use binding is quite similar to the Let binding in that it binding a value to the result of an expression. The key difference is that the Use binding is designed to work with IDisposable types and will automatically Dispose of the value when it is no longer in scope. This is quite similar to the .NET using keyword, though I do not believe that the F# Use binding will be exactly the same as the .NET using keyword semantics, as the .NET using keyword is really a try / finally with a Dispose() call in the finally.

We have already seen an example of the Use binding in the last post we did on Formatting Text, but just to remind ourselves lets have a look at that again

use sw = new StreamWriter(@"c:\temp\fprintfFile.txt")
fprintf sw "This is a string line %s\r\n" "cat"
fprintf sw "This is a int line %i" 10
sw.Close()

In this example the Use binding ensures that the StreamWriter will have its Dispose() method called after the sw.Close() call seen above.

A couple of points

Use Only Works with IDisposables, and you will get a compilation error should you try and use it with anything else, as shown below

image

As the Dispose() method is called at the end of a Use binding, care should be taken to not return a value that was bound using a Let.

i.e : Don’t do this:

let Write =
    use sw = new StreamWriter(@"c:\temp\fprintfFile.txt")
    sw

If you absolutely need to pass an IDisposable around that are part of a Use binding, you can use a callback instead. So something like this would work, but I would stop and ask yourself have you got your design right if you are doing this sort of thing

let Write callback =
    use sw = new StreamWriter(@"c:\temp\fprintfFile.txt")
    fprintf sw "Write is writing to the StreamWriter"
    callback sw
    sw

let callback sw = fprintf sw "sw is the StreamWriter"
let disp = Write callback

Do

Use a do binding is used to execute code without defining a function or value. A Do binding MUST always return Unit (no value / void essentially). In a lot of cases you will be able to omit the Do binding value and things will work just as expected.

Here are some examples of using the Do binding

do printf "doing the do"
//oh oh not a unit
do printf "print a sum %i" 1 + 1
do 1 + 1

If I instead show you a screen shot of the code above you will see that the compiler complains if you try and use Do with a Non Unit result.

image

You have 2 choices as he error message states, which is to either

  1. Use the forward pipe operator to pipe the results to ignore
  2. Create a Let binding

I have shown an example of each of these below:

let x = 1 + 1
do printf "print a sum %i" x
do (1+1 |> ignore)

You can read more about the Let binding using MSDN : http://msdn.microsoft.com/en-us/library/dd393786.aspx

Let! Use! ad Do!

Although I don’t want to discuss these just yet, you may on occasion see Let! / Use! / Do!, and when you do these are part of what is known as a computation expression. The place you are most likely to see these is within F#s Asynchronous Workflows which we will be going through in one of the final articles. If I man enough I may even attempt to explain how you can create your own “Computation Expression” though they are quite an abstract concept and are quite an advanced topic so now is not the time for them.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Sacha Barber
Software Developer (Senior)
United Kingdom United Kingdom
I currently hold the following qualifications (amongst others, I also studied Music Technology and Electronics, for my sins)

- MSc (Passed with distinctions), in Information Technology for E-Commerce
- BSc Hons (1st class) in Computer Science & Artificial Intelligence

Both of these at Sussex University UK.

Award(s)

I am lucky enough to have won a few awards for Zany Crazy code articles over the years

  • Microsoft C# MVP 2015
  • Codeproject MVP 2015
  • Microsoft C# MVP 2014
  • Codeproject MVP 2014
  • Microsoft C# MVP 2013
  • Codeproject MVP 2013
  • Microsoft C# MVP 2012
  • Codeproject MVP 2012
  • Microsoft C# MVP 2011
  • Codeproject MVP 2011
  • Microsoft C# MVP 2010
  • Codeproject MVP 2010
  • Microsoft C# MVP 2009
  • Codeproject MVP 2009
  • Microsoft C# MVP 2008
  • Codeproject MVP 2008
  • And numerous codeproject awards which you can see over at my blog

Comments and Discussions

 
SuggestionLittle more addition here. PinmemberVallarasuS3-Mar-14 11:24 
GeneralRe: Little more addition here. PinmvpSacha Barber3-Mar-14 11:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150414.1 | Last Updated 3 Mar 2014
Article Copyright 2014 by Sacha Barber
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid