let is the F# keyword used to bind any value to a name, it's used to bind the so called primitive types such as a
string or an
integer, to bind to a function or more complex structures such as arrays or records.
Here's how you can bind a string to an identifier named
let x = "some text"
const there's only
let and since in F# every value is immutable by default, that snippet is the equivalent of a constant.
let in F# is different than
We're going to see more on functions later but here's how you can bind a function to an identifier named
let add x y = x + y
In the above snippet a function that adds two integers is being bound to an identifier named
add and then two values are being bound to the identifiers
In F#, bindings are immutable by default which means that normally one can't reassign a value to a named binding, rather, if you try to do so using
let what will happen is that you'll shadow an existing binding.
For instance, in the following example:
let x = "the answer" let x = 42
In this case
x is not being redefined nor its type is being changed from a
string to an
int, instead there are two different bindings with the same name
x to different values. Of course, this example is not very useful because one binding is happening right after the other, but consider the following:
let printName name = let stripLastName name = if (String.exists (fun c -> c = ' ') name) then name.Split([|' '|]). else name printfn "%s" name // Will print "John Doe" printfn "%s" (stripLastName name) // Will print "John" printName "John Doe"
Don't worry too much if you don't fully grasp the above code, the main goal of that snippet is to demonstrate that the function
printName expects an argument named
name and in its body it defines another function
stripLastName that also expects an argument
name. Inside the scope of
name argument is creating a new binding and thus shadowing the
name argument received on the
printName function. And that can be asserted by the two prints at the end of the
The main differences that the
letto define a named variable, and its value can be reassigned which is not the case in F#.
letis scope bound, so one can declare a new variable with an already used name as long as it is in a different scope, in F# that can be done within the same scope.