Variables

 Variables Fundamentals

 Introduction
 A variable is a section of the computer memory used to temporarily hold a value. Reserving a portion of memory is referred to as declaring a variable. There are rules you must follow.

To declare a variable, use an operator named let. Based on this, declaring a variable in F# is also referred to as let binding.

Follow the let keyword by a name for the variable, and assign a value to it using the assignment operator "=". The formula to follow is:

`let VariableName = Value`

Here is an example:

`let x = 16`

A declaration can end with a semicolon or not. The above declaration can also be written as:

`let x = 16;`

Although we declared and initialized the variable in one line, if you want, you can put the initialization on another line. If you decide to do this, the code on the next line must be indented. Here is an example:

```let x =
16```

or

```let x =
16;```

Instead of declaring one variable, you may want to declare many. To do this, you can declare each on its line, using its own let keyword and its own initialization. Here are examples:

```let x = 16;
let y = 24;
let z = 58;```

As an alternative, you can use one let keyword and list the variables separated by commas with the group followed by the assignment operator "=". After the assignment, give the list of values for each variable in the order they appear in the initialization. Here is an example

`let x, y, z = 16, 24, 58;`

The variables don't have to be of the same type. Here is an example:

`let x, y, z = 16, "John", 'M';`

Remember that if the line of initialization is too long, you can continue it on the next line and remember to indent it. Here is an example:

```let x, y, z =
16, "John", 'M';```
 Names in F#

The name of a variable or of a function must follow some rules. For example, avoid the following names:

 abstract and as assert base begin class default delegate do (Function) do do done downcast downto elif else end (class) end (if) exception extern false finally for fun function global if ignore inherit inline in interface internal lazy let match member module mutable namespace new not null of open or override private public rec ref return static struct then to true try type unit upcast use val void when while with yield

Also avoid using the following words when naming anything:

 asr atomic break checked component const constraint constructor continue eager event external fixed functor include land lor lsl lsr lxor method mixin mod object parallel process protected pure sealed sig tailcall trait virtual volatile

 Operators in F#

As a normal computer language, F# includes many operators that can be used to perform varioous types of operations. Most operators use only one symbol. Some operators use a combination of symbols. Some operators use words. The operators are:

 : ' " ( = % \ / | ** := && || || | < << <= > >> >= <> |> <| -> <- <<<
 Introduction to Data Types

 Fundamentals

When you declare (or bind) a variable and assign a value to it, if you don't explicitly indicate its type, the compiler implicitly determines the variable's type. Still, F# supports different types of values.

 An Infered Language

F# is an infered language. This means that, when declaring a variable, you don't have to specify its data type but you must initialize it. When you do this, the compiler will "infer" the data type; that is, the compiler will decide about the appropriate type to apply to the variable.

As a result, you can omit specifying the data type of a variable and let the compiler take care of it, or you can specify it. If you decide to specify the data type of a variable, follow its name with a colon and the data type. The formula to follow is:

`let VariableName : DataType`
 Introduction to Strings

 Overview

A string is a group of characters or symbols considered as one entity. To initialize a string, include its value in double-quotes. Here is an example:

`let message = "Welcome to the wonderful world of functional programming!";`

To display a string value using either the printf or the printfn function, use %s as the placeholder of the variable. Here is an example:

```let message = "Welcome to the wonderful world of functional programming!";

printfn "%s" message;```

A string is represented by a data type named string. Therefore When declaring a variable, if you want to indicate that it is a string, use the string data type. Here is an example:

```let message : string = "Welcome to the wonderful world of functional programming!";

printfn "%s" message;```

When declaring a string variable, you can initialize it with an empty space, a character, a symbol, a word, or a group of words. The value given to a string must be included in double-quotes. Here are examples:

```let category = "1";
let gender = "M";
let employee = "Garçon Hérand";

printfn "Great Corporation";
printfn "Employee: %s" employee;
printfn "Gender:   %s" gender;
printfn "Status:   %s" category;```

This would produce:

```Great Corporation
Employee: Garçon Hérand
Gender    M
Status:   1

Press any key to continue . . .```

If you have a long string that you want to span on more than one line, cut its sections with a back slash each (although the second line in the following example is indented, you don't have to indent). Here is an example:

```let message = "Welcome to the wonderful world \
of functional programming!";

printfn "%s" message;```

There are many other issues related to strings. We cannot review them now.

There are many other issues related to strings. We cannot review them now.

 Operations on Strings: Concatenation

String concatenation consists of adding one string to another. This is done using the addition operation. Here is an example:

```let userName = "pjacobson"
let emailDomain = "@yonson.com"

This would produce:

`Employee Email: pjacobson@yonson.com`

In the same way, you can use as many addition operators as necessary to concatenatte strings. Here is an example:

```let firstName = "Philippe"
let lastName = "Jacobson"
let fullName = firstName + " " + lastName

printfn "Employee Name: %s" fullName```

This would produce:

`Employee Name: Philippe Jacobson`
 Characters

 Introduction

A character is letter (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, or Z), a digit, or a symbol that can be visually represented and recognized by the computer. It can also be a digit (0, 1, 2, 3, 4, 5, 6, 7, 8, 9). Examples of symbols are: ` ~ ! @ # \$ % ^ & * ( ) - _ = + [  ]  \ | ; : ' < ? . / , > "

To use a value that represents a character, declare a variable and initialize with a letter, a digit, or a symbol in single-quotes.  Here is an example:

`let gender = 'F';`

To display the value, in the double-quotes of printf or printfn, use %c as the placeholder of the variable. Here is an example:

```let gender = 'F';

printf "Student Gender: ";
printfn "%c" gender;```

This would produce:

`Student Gender: M`

When declaring the variable, to indicate that it is a character, use the char keyword. Here is an example:

```let gender : char = 'F';

printf "Student Gender: ";
printfn "%c" gender;```
 Escape Sequences

An escape sequence is a special character that displays non-visibly. For example, you can use this type of character to indicate the end of a line; that is, to ask the program to continue on the next line. An escape sequence is represented by a backslash character, \, followed by another character or symbol. For example, the escape sequence that moves to the next line is \n.

An escape sequence can be included in the quotes of printf or printfn. The escape sequences are:

 Escape Sequence Name Description \b Backspace Takes the cursor back \t Horizontal Tab Takes the cursor to the next tab stop \n New line Takes the cursor to the beginning of the next line \r Carriage return Causes a carriage return \" Double Quote Displays a quotation mark (") \' Apostrophe Displays an apostrophe (') \\ Backslash Displays a backslash (\) \0 Null Displays a null character \uXXXX Unicode Character Used to display the equivalent representation of a symbol given in hexadecimal format \UXXXXXXXX Unicode Character Used to display the equivalent representation of a symbol given in hexadecimal format

Here is an example:

```let gender : char = 'M';

printf "Student Gender: ";
printfn "%c\n" gender;```

In some cases, you will want to treat an escape sequence in a particular, or to simply ignore it. In other words, you may want the compiler to ignore that a combination of \ and a character is an escape sequence. A typical example is in specifying the path to a file in the computer. In this case, you must create a verbatim string.

To create a verbatim string, start it with the @ sign outside the opning double-quote. Here is an example:

`let fileName = @"G:\Corporate Presentations\References\Introductory Material.docx"`

If you precede a string value with the @ sign, all escape sequences in the string would be ignored, except for the double-quotes. If you want the double-quotes to be ignored, start and end the string with three double-quotes. Here is an example:

`let fileName = @"@"@"G:\Corporate Presentations\References\Introductory Material.docx"@"@"`
 Integral Variables

 The Byte Data Type

A byte is an unsigned number whose value can range from 0 to 255 and therefore can be stored in one byte. To declare a variable that would hold a small natural number, use the byte keyword.

Here is an example that uses the byte data type:

```let age:byte = 14uy;

printf "Student Age: ";
printfn "%d" age;```

Make sure you don't use a value that is higher than 255 for a byte variable, you would receive an error.

Instead of a decimal number, you can also initialize an integral variable with a hexadecimal value. When doing this, make sure the decimal equivalent is less than 255. Here is an example:

```let number = 0xFE;

printfn "Number: %d" number;```

This would produce:

```Number: 254
Press any key to continue . . .```
 Signed Bytes

A byte number is referred to as signed if it can hold a negative of a positive value that ranges from -128 to 127, which can therefore fit in a byte. To initialize a signed byte variable, add y to its value. Here is an example:

`let roomTemperature = -88y;`

To represent the value of a signed byte variable, use %d. Here is an example:

```let roomTemperature = -88y;

printfn "When we entered, the room temperature was %d" roomTemperature;```

This would produce:

`When we entered, the room temperature was -88`

To declare a variable for that kind of value, use the sbyte keyword. Here is an example:

```let roomTemperature : sbyte = -88y;

printfn "When we entered, the room temperature was  %d" roomTemperature;```
 Short Integers

You may need a variable that can hold a value from -32768 to 32767. Here is an example of declaring such a variable:

```let schoolEffective = 1400;

printfn "School Effective: %d" schoolEffective;```

This would produce:

```School Effective: 1400
Press any key to continue . . .```

Since the byte type is used for (very) small numbers, if you want to indicate that your variable will hold values between -32768 to 32767, specify its data type as int16. Here are two examples:

```let numberOfPages : int16 = 842s;
let temperature : int16 = -1544s;

printfn "Number of Pages of the book: %d" numberOfPages;
printfn "Temperature to reach during the experiment: %d degrees\n" temperature;```

This would produce:

```Number of Pages of the book: 842
Temperature to reach during the experiment: -1544 degrees```

Because a short integer handles numbers that are larger than the signed byte, any variable you can declare for a signed byte can also be declared using int16.

 Unsigned Short Integers

If a variable must hold positive and relatively small numbers, it is referred as an unsigned short integer. To use such a variable, when initializing it, add a us suffix to its value. Here are examples:

```let numberOfTracks = 16us;
let musicCategory = 2us;

printfn "This music album contains %d tracks" numberOfTracks;
printfn "Music Category: %d" musicCategory;```

This would produce:

```This music album contains 16 tracks
Music Category: 2```

An unsigned short integer can hold numbers that range from 0 to 65535 and therefore can fit in 16 bits. If you want to indicate the data type of the variable, use uint16. Here are examples:

```let numberOfTracks:uint16 = 16us;
let musicCategory:uint16 = 2us;

printfn "This music album contains %d tracks" numberOfTracks;
printfn "Music Category: %d" musicCategory;```
 Signed Integers

You may want to use a variable that can hold any type of natural number. Here is an example:

```let coordX = 12;
let coordY = -8;

printfn "Cartesian Coordinate System: P(%d, %d)" coordX coordY;```

When executed, the program would produce:

`Cartesian Coordinate System: P(12, -8)`

You may want a variable that can hold small to (very) large negative or positive numbers, such as values between 2,147,483,648 and 2,147,484,647. Such numbers are referred to as signed integers. To indicate this when declaring a variable, specify its data type as int.

When initializing an integral variable, instead of a decimal number, you can also initialize it with a hexadecimal value whose decimal equivalent is less than 2,147,484,647. Here is an example:

```let number = 0xF0488EA;

printfn "Number: %d" number;```

This would produce:

```Number: 251955434
Press any key to continue . . .```
 Native Integers

You can declare a variable that will hold values as a native integer. When initializing the variable, add an n suffix to its value. To display its value, use %d. Here is an example:

```let number : nativeint = 16n;

printfn "Number = %d" number;```

This would produce:

```Number = 16
Press any key to continue . . .```
 Long Integers

To declare a variable that can hold large values, initialize the variable with the desired value. Here is an example:

```let population = 72394475;

printfn "Country Population: %d" population;```

This would produce:

```Country Population: 72394475
Press any key to continue . . .```

When initializing the variable, to indicate that it represents a long integer, add L to its value. Here is an example:

```let population = 72394475L;

printfn "Country Population: %d" population;```

To indicate the data type of a long integer variable, you can use the int64 data type. Here is an example:

```let population : int64 = 72394475L;

printfn "Country Population: %d" population;```
 Unsigned Integers

If the variable must hold only positive natural numbers, you can declared it using the uint32 keyword, which is used for values that range from 0 to 4,294,967,295. Here is an example:

```let dayOfBirth : uint32 = 8u;
let monthOfBirth : uint32 = 11u;
let yearOfBirth : uint32 = 1996u;

printfn "Red Oak High School";
printfn "Student Date of Birth: %d/%d/%d" monthOfBirth dayOfBirth yearOfBirth;```

This would produce:

```Red Oak High School
Student Date of Birth: 11/8/1996```
 Unsigned Native Integers

To declare a variable for an unsigned native integer, when initializing the variable, add a un suffix to its value. To display its value, use %d. Here is an example:

```let number : unativeint = 16un;

printfn "Number = %d" number;```
 Unsigned Long Integers

An unsigned long integer is a very large positive number. To support those types of values, the F# language provides the uint64 data type. When initializing the variable, add UL to its value.

 Operations on Integers

 Unary Operations

To indicate that a number or a variable is positive, either don't add any operator to it or add + to its left.

To indicate that a number is negative, add a - sign to its left.

Infinity is the highest decimal number that exists. To support it, the F# language provides the infinity keyword. Here is an example of accessing it:

```let population = infinity;

printfn "Population: %.3f" population```

This would produce:

```Population: Infinity
Press any key to continue . . .```
 Arithmetic Operations

Integral numbers support all the regular arithmetic operators learned in elementary school:

• The + sign is used to add two or more numbers
• The - symbol is used to subtract one number from another
• The * operator is used to multiply two or more numbers
• The division represented by / is used to divide a first number, called a numerator, by another number, called the denominator. The formula to use is
`numerator / denominator`
The denominator must not be equal to 0
• The % operator is used to find the remainder when a numerator is divided by a denominator
 Byte-Shift Operations

The F# language supports operations that consist of moving the values, namely 0 or 1, stored in the bits of the computer memory:

• The <<< operator is used to shift a certain number of bytes from a number (actually the memory area where a number is stored) to its left in the computer memory. Here is an example:
```let a = 248;
let b = 5;
let leftShift = a <<< b;

printfn "%d shifted to the left by %d bytes is %d" a b leftShift;```
This would produce:
```248 shifted to the left by 5 bytes is 7936
Press any key to continue . . .```
• The >>> operator is used to shift a certain number of bytes from a number to its right
 Bitwise Operations

A bitwise operation consists of adding or removing (actually replacing or switching) the 1 and 0 values stored in the computer memory:

• To add two bits, use the &&& operator. This called the bitwise-AND operator. Here is an example of applying this operator:
```let a = 248;
let b = 125;
let bitwise = a &&& b;

printfn "The bitwise-AND operation between %d AND %d is %d" a b bitwise;```
This would produce:
```The bitwise-AND operation between 248 AND 125 is 120
Press any key to continue . . .```
• The bitwise OR operation consists of reversing the value of a bit. During this operator, if the value of a bit is 1, it is changed to 0, and vice-versa. To perform this operation, use the ||| operator. Here is an example:
```let a = 248;
let b = 125;
let bitwise = a ||| b;

printfn "The bitwise-OR operation between %d and %d is %d" a b bitwise;```
This would produce:
```The bitwise-OR operation between 248 and 125 is 253
Press any key to continue . . .```
• To perform a bitwise XOR operation, use the ^^^ operator
 Real Numbers

 Introduction

A real number is a number that displays a decimal part. This means that the number can be made of two sections separated by a symbol that is referred to as the Decimal Separator or Decimal Symbol. This symbol is different by language, country, group of languages, or group of countries. In US English, this symbol is the period as can be verified from the Regional (and Language) Settings of the Control Panel.

On both sides of the Decimal Symbol, digits are used to specify the value of the number. The number of digits on the right side of the symbol determines how much precision the number offers.

 Floating-Point Numbers

F# supports floating-point numbers that range from ±1.5 — 10−45 to ±3.4 — 1038 with a precision of 7 digits that can fit in 32 bits. To declare such a variable, add f or F to its value. Here is an example:

`let distance = 12f;`

To indicate the data type of the variable, you can use either the single or the float32 data type. Here is an example:

`let distance:single = 12f;`
 Double-Precision Numbers

When a variable is larger than the single can handle and requires more precision, you should declare it using either the float or the double keyword. Here is an example:

```let number = 62834.9023;

printfn "Number: %f" number;```

This would produce:

```Number: 62834.9023
Press any key to continue . . .```

A variable declared as double uses 64 bits to store very large numbers ranging from ±5.0 x 10−324 to ±1.7 x —10308 with a precision of 15 or 16 digits.

 Decimals

The decimal data type can be used to declare a variable that would hold significantly large values that can be stored in a combination of 128 bits. You declare such a variable using the decimal keyword. The values stored in a decimal variable can range from ±1.0 — 10−28 to ±7.9 — 1028 with a precision of 28 to 29 digits.

After declaring a decimal variable, you can initialize it with a natural number. To indicate that the variable holds a decimal value, when initializing it, add an M suffix to its value. Here is an example:

```let hourlySalary: decimal = 24.25M;

printfn "Hourly Salary = %f" hourlySalary;```

This would produce:

`Hourly Salary = 24`

As seen in previous sections and this one, when declaring and initializing a real variable, the suffix you give to its assigned value indicates to the compiler the actual type of value and the type of memory that would be allocated for the variable.

 Operations on Decimal Numbers

 Arithmetic Operations

Real numbers support the regular arithmetic operators that are the addition, the subtraction, the multiplication, and the division.

 The Power of a Number

Decimal numbers support the operation that consists of raising one number to the power of another number. This is done using the ** operator. Here is an example:

```let a = 8.25;
let b = 5.14;
let power = a ** b;

printfn "%.2f raised to %.2f = %.2f" a b power;```

This would produce:

```8.25 raised to 5.14 = 51353.88
Press any key to continue . . .```

This operation is not supported on natural numbers. If you want to perform it on integers, simply add .00 to each number.

 Options on Variables

 Mutable Variables

When you declare and initialize a variable by binding it to a constant value, the compiler reserves memory for that variable and stores the value in the reserved memory. Here are examples:

```let firstName = "Mark";
let lastName  = "Lambert";

printfn "First Name %s" firstName;
printfn "Last Name: %s" lastName;```

This would produce:

```First Name Mark
Last Name: Lambert
Press any key to continue . . .```

Normally, you cannot change the value of a variable after it has been declared and initialized. That is, you cannot remove the value in that reserved memory to replace it with another value. Consider the following example:

```let firstName = "Mark";
let lastName  = "Lambert";

printfn "First Name %s" firstName;
printfn "Last Name: %s" lastName;

lastName  = "Alley";
printfn "Last Name: %s" lastName;```

Notice that the variable lastName changes value. The above program would produce:

```First Name Mark
Last Name: Lambert
Last Name: Lambert
Press any key to continue . . .```

Notice that the lastName variable is given a new value the second time but when that variable is accessed a second time, it still has its original value. The variable is said to be immutable: its value cannot change after it has been initialized.

If you want to be able to change the value of a variable, you must indicate that it is mutable. To do this, when declaring the variable, precede it with the mutable keyword. Here is an example:

`let mutable lastName = "Lambert";`

You can then use the variable any way you want. When a variable has been declared mutable, you can change its value by assigning another value to it. To do this, instead of =, use the <- operator. Here is an example:

```let firstName = "Mark";
let mutable lastName  = "Lambert";

printfn "First Name %s" firstName;
printfn "Last Name: %s" lastName;

lastName <- "Alley";

printfn "First Name %s" firstName;
printfn "Last Name: %s" lastName;```

This would produce:

```First Name Mark
Last Name: Lambert
First Name Mark
Last Name: Alley
Press any key to continue . . .```
 Reference Cells

The values you declare in your programs are stored in the computer memory when your application starts. Every one of those values has or uses an address as its location. The compiler can refer to that address to locate the variable and use its value. You too can get a reference to that address and use it as you see fit. For example, you can change the value that the variable located at a parcilar address.

To get a reference to a variable, you use the ref keyword. To use it, when declaring a vaible, add this keyword between = and the initial value stored in the variable. Here is an example:

`let x = ref 16`

To get the value the variable refers to, you must dereference the variable. This is done by applying the ! operator to the name of the variable. Here is an example:

```let price = ref 45.00;

printfn "Item Price: \$%0.02f\n" !price;```

This would produce:

```Item Price: 45.00

Press any key to continue . . .```

When necessary, you can change the value of the variable by assigning another value to it. This is done using the := operator. Here is an example:

```let price = ref 45.00;

printfn "Item Price: \$%0.02f" !price;

price := 38.75;

printfn "Discount Price: \$%0.02f\n" !price;```

This would produce:

```Item Price: \$45.00
Discount Price: \$38.75

Press any key to continue . . .```

This feature works likt that of mutable variables and allows you to declare a variable whose value you plan to change while the program is running.