Use variables to store values
All programs usually consist of many steps where the program operates on data. As part of running all those steps, it's common to store the intermittent result, the data, in a named reference. Then you can read or manipulate the data later. Named references are commonly referred to as variables.
Variables, bind a value
Variables are named references bound to a value, that you want to keep referring to in your code. In F#, it's thought of as binding a value. So what you do is to assign, or bind, a value to a named reference, a variable. To bind a value, you use the let
keyword, a name for your reference and assign a value to it, like in the below code:
let name = "Chris"
name
is the named reference and "Chris" its bound value.
After a value is assigned to a variable, it can't be changed, it's immutable. The following code wouldn't compile and produces an error saying something like "error FS0027: This value is not mutable."
let name = "Chris"
name <- "Luis" // not allowed
Make it mutable
You can change variables, but you need to signal that you want to make them mutable. By using the keyword mutable
in your variable definition, you can change a value without a compilation error, like in the following code:
let mutable name = "Chris"
name <- "Luis" // this statement is now allowed
Variable types
A range of different types exist in F#. Many of the types have to do with storing numbers of different sizes and with or without decimals. Other types are associated with text string or Boolean variables. Here's a list of types that you're likely to encounter when you start learning F#.
Type | Description |
---|---|
bool | possible values are true or false |
int | Values from -2,147,483,648 to 2,147,483,647. |
string | Unicode text |
float, double | A 64-bit floating point type. |
Type is inferred
When you declare a variable, you can do so with or without type. If you don't provide a type when you declare a variable, the F# compiler makes a best guess on what the type should be by the value you assign to the variable. Consider the following statements:
let age = 65 // int
let PI = 3.14 // float
let name = "my name" // string
The compiler infers what the types should be, and it's right. You can also be more explicit about what you want the type to be. To assign a data, you use the syntax variableName:<type>
, like in this code:
let sum:float = 0.0
Print to the screen
You often want to be able to print to the screen. It could be for various reasons, such as:
- Application output: The application is doing some sort of calculation, and you want to see the output.
- Debugging: As part of debugging your code, you might have to output the result at a given point to understand what's going wrong.
There are other reasons for wanting to output to the screen, but the preceding two scenarios are the most common.
So how would you print to the screen? In F#, there are three different functions you can use. They're printf
, printfn
, and even Console.WriteLine
. So what's the difference?
printf
: It prints tostdout
inline (no newline character).printfn
: It prints tostdout
adds a newline character.Console.WriteLine
: This function is from theSystem
namespace and works in all .NET languages.
Now you know the difference, but which one should you use? Well, printf
and printfn
are considered more idiomatic and preferred in F#.
Formatting
As part of printing to the screen, you might want to combine text and numbers. Or you might want the output to be formatted in a certain way, such as by using:
Positional arguments: To format, you can use a .NET function like
String.Format
, which uses positional arguments likeString.Format("My name is {0} and I live in {1}", "Chris", "UK")
.String interpolation: Another way to combine variables and text is to use something called interpolation. To use it, you need to precede the string with a
$
sign and indicate placeholders with brackets{}
. Here's an example of using interpolation:let name = "Luis" let company = "Microsoft" printfn $"Name: {name}, Company: {company}"
You can also add expressions in between the brackets, like so:
let firstNumber = 2000 let secondNumber = 21 printfn $"The year is: {firstNumber + secondNumber}"
Note
There's no type checking using interpolation, so it might seem straightforward to use. Be sure to combine things correctly.
Specifiers: You can also use format specifiers as part of what you're trying to print. Using specifiers is the most commonly used way to format in F#. Here's an example:
let name = "Chris" printf "Hi %s" name // prints: Hi Chris
Here you can see how the formatter
%s
is used to mix the first string with the variablename
.Note
When you use formatters like %s or %i, the compiler checks types. If your positional argument isn't of the type you've specified, it throws an error.
Format specifiers
There are many format specifiers. Here are some you're likely to encounter.
Specifier | Description | Example |
---|---|---|
%s | Used for strings and unescaped contents | printf "Hello %s" name |
%d, %i | Formatted as a decimal integer, signed if the basic integer type is signed | printf "Age: %i" 65 |
%b | Boolean true or false |
printf "Setting on: %b" true |
There's more information on formatting. If you want to know about all the capabilities, see the formatting in F# doc.