Back to: F# Journey
By default all variables in F# are immutable. Hence.. we can not call them “variables” anymore. The term “value” fits better.
Here is a simple example of an immutable value:
let val1 = 2 printfn "%d" val1
Now when you try to change the value like in the code below (line 2) the compiler will bring this warning:
This expression should have type ‘unit’, but has type ‘bool’. Use ‘ignore’ to discard the result of the expression, or ‘let’ to bind the result to a name.
let val1 = 2 val1 = 4 printfn "%d" val1
The compiler does not even recognize this as an valid value assignment! “val1 = 4” is a valid comparison, and the compiler says that you either have to save the result in a value with the ‘let’ function or to ignore it with ‘ignore’.
But how can I change the value? Mark the value as mutable and use the <- for the assignment.
let mutable val1 = 2 val1 <- 3 printfn "%d" val1
Going back to the compiler message: If you do an comparison as in the code above you can store the result in a value.
let val1 = 2 let comp = val1 = 4 printfn "%b" comp
The result will be “false”. (Well at least the value comparison works the same way as in C#) ðŸ™‚
Functions in F# always have return values. F# will automatically determine the return value. In our case here “val1 = 4”, the return value is of type ‘bool’. If we don’t need the return at all, then we can simply ignore it.
let val1 = 2 val1 = 4 |> ignore printfn "%d" val1
Immutable values in functional programming have some advantages:
– Easier to share state. Locking not needed for immutable data.
– We have less side effects. Once the value is set it can’t be changed during the program flow.
– As an developer, you are more aware of what your code is changing or not.
– The code is more clear. Let’s take this C# code as an example:
var myContract = new InsuranceContract(startDate, endDate); myContract.Extend(DateTime.Now.Add(10));
Now guess what the state of myContract object is… Does “Extend” change the endDate property? Or does it create a new InsuranceContract instance? We don’t know.
In F# it’s clear. Because we can’t change the endDate value, the “Extend” function has to return a new InnsuranceContract instance.