F# Let Keyword: let mutable, Errors

Understand the let, let mutable and lightweight syntax. See functions, variables and temporary variables.

Let. We declare values and functions in F# with let. Y equals 100. We introduce a binding to the value 100 to the identifier Y. We cannot change the meaning of Y later.

With the mutable keyword, we create mutable values (variables). These can be changed as a program executes. With let (part of the lightweight syntax) we also declare functions.

Mutable example. This first example uses the "mutable" keyword on a variable. We bind the identifier "number" to the value 100 and then reassign "number" to 200.
Left arrow: This indicates assignment. In a declaration, we use the equals sign, but we cannot declare the same thing twice.
F# program that uses let mutable variable // Create a mutable variable. let mutable number = 100 printfn "%d" number // Reassign the variable to another value. number <- 200 printfn "%d" number Output 100 200

Not mutable error. This problem is encountered by many new F# developers. We try to assign a value that is not mutable. We can fix this by adding a mutable keyword to "color."
However: Using two values is a better option (at least on simple things) than a variable that has a change in meaning.
F# program that causes not mutable error let color = "green" printfn "%s" color // This causes an error. color <- "blue" printfn "%s" color Output error FS0027: This value is not mutable

Separate values. Consider this program. We do not reassign any variable. Instead we just use two separate let-values. The meaning of this program is easy to understand.
And: Time does not need to be considered to know the values color1 and color2: they never change. The program is easy to reason about.
F# program that uses let constants // Use two identifiers for the values. let color1 = "magenta" printfn "%s" color1 let color2 = "crimson" printfn "%s" color2 Output magenta crimson

Lightweight function. The F# language uses a lightweight syntax. This considers indentation. It requires the "let" keyword for function declarations.
Here: The function "greeting" is declared. It receives one string parameter, and returns a string (a type inferred by the compiler).
Fun: To specify a lambda expression, we must use the "fun" keyword instead of the let-keyword.
F# program that uses let function // Use let keyword to create a function that receives a string. // ... It returns another string. let greeting (name : string) = "Hi " + name.ToUpper() + "," // Call the function and print its result. printfn "%s" (greeting "visitor") printfn "How are you?" Output Hi VISITOR, How are you?

Temporary values. Sometimes a function is long and complex. Having temporary (intermediate) values makes it easier to reason about. We can use let-values inside a "let" function.
Here: This function concatenates some strings. We use value1 and value2 inside of it to make it easier to read.
F# program that uses let, temporary values let combineStrings left right = // Create a temporary string based on the first argument. let value1 = "[" + left + "]" // Based on the second argument. let value2 = "{" + right + "}" // Return another string. // ... This is not optimally fast. value1 + "..." + value2 // Call the function with two string arguments. let result = combineStrings "cat" "dog" printfn "%s" result Output [cat]...{dog}

Block comments. Sometimes a let statement spans multiple lines. This is not easy to comment out with single-line comments. But with a block comment we can temporarily erase it.
F# program that shows multiline comment (* let modify x = List.map (fun y -> y * 2) x |> List.sum *)

Lightweight syntax. Indentation is important in F#. We must line up statements in the correct position when using lightweight syntax.

A review. Special features like inferred types make F# fast to write and easy to understand. With "let" we solve many problems: we specify values, variables and functions.

© 2007-2020 Sam Allen. Every person is special and unique. Send bug reports to info@dotnetperls.com.