## Variables

So, to declare variables we can use `let`

keyword. For example:

`let x = 1;;`

We can also use `;;`

to separate expressions. For example:

```
let x = 1;;
let y = 2;;
```

We can do something like this:

`let x = 50 in x * x;;`

Obs: It will return`2500`

. But`x`

is not defined outside of`in`

block. So, we can’t use`x`

outside of`in`

block. If you try to print out`x`

value, you will have an error.

## Functions

We can define functions with `let`

keyword. For example:

`let square x = x * x;;`

Anonymous functions are defined with `fun`

keyword. Example:

`map (fun x -> x * 2) [1; 2; 3];;`

### Recursion

We can do recursion with `let rec`

keyword. For example:

```
let rec range a b =
if a > b then []
else a :: range (a + 1) b;;
```

Obs: The difference between`let`

and`let rec`

is that if we have used`let`

we couldn’t use`range`

function inside of`range`

function, we would have an error.

## Float x Int

OCaml needs you to explicitly convert `int`

to `float`

and vice versa. For example:

```
let x = 1;;
let y = 2.0;;
let z = float_of_int x +. y;;
```

Obs: The`+.`

operator is used to sum`float`

numbers. If you try to sum`int`

numbers with`+.`

operator, you will have an error. The same for the otherwise case.

## Pattern Matching

We can use the `match`

and `with`

keywords to do pattern matching. For example:

```
let rec factorial n =
match n with
| 0 | 1 -> 1
| _ -> n * factorial (n - 1);;
```

Obs: The`_`

is used to match any value. We could replace the last line with`| x -> x * factorial (x - 1)`

. It would be the same. The`x`

is a variable that receives the value of`n`

in the case. Of course`x`

doesn’t exist outside of the the case.

We can also simplify the pattern matching by using the `function`

keyword. For example:

```
let rec factorial = function
| 0 | 1 -> 1
| n -> n * factorial (n - 1);;
```

Obs: The`function`

keyword introduces pattern matching directly. The parameter is not named, but we can use it in the cases (hmm).

## Lists

Lists are ordered collections of elements of the same type. For example:

```
# [];;
- : 'a list = []
# [1; 2; 3];;
- : int list = [1; 2; 3]
# [false; false; true];;
- : bool list = [false; false; true]
# [[1; 2]; [3; 4]; [5; 6]];;
- : int list list = [[1; 2]; [3; 4]; [5; 6]]
```

The `::`

(cons) operator adds an element to the beginning of a list. For example:

```
# 1 :: [];;
- : int list = [1]
# 2 :: [1];;
- : int list = [2; 1]
```

The `@`

(append) operator concatenates two lists. For example:

```
# [1; 2] @ [3; 4];;
- : int list = [1; 2; 3; 4]
```

Non-empty lists have a `head`

(it’s first element) and a `tail`

(the list of the rest of the elements). For example:

```
# let x = [1; 2; 3];;
val x : int list = [1; 2; 3]
# List.hd x;;
- : int = 1
# List.tl x;;
- : int list = [2; 3]
```

We can create functions that operates over lists using pattern matching. For example:

```
# let rec total l =
match l with
| [] -> 0
| h :: t -> h + total t;;
val total : int list -> int = <fun>
# total [1; 3; 5; 3; 1];;
- : int = 13
```

Obs: The`h`

is the head and the`t`

is the tail. We use the`::`

operator to desconstruct here.

Another example:

```
let rec length l =
match l with
| [] -> 0
| _ :: t -> 1 + length t;;
```

Obs: This function will not operate just a list of integers as the latest example, it’ll operates lists of any types. So the list in the parameter is of type`'a list`

(pronouncedalpha list), and the function is calledpolymorphicsince the type isn’t relevant.

Let’s write a `map`

function that will take a function and a list as parameters and will apply the function to every element of the list and return results, just like a map:

```
let rec map f l =
match l with
| [] -> []
| h :: t -> f h :: map f t;;
```

Example of usage (using the `total`

function we’ve created before):

```
# total;;
- : int list -> int = <fun>
# map total [[1; 2]; [3; 4]; [5; 6]];;
- : int list = [3; 7; 11]
# map total [1; 2; 4];;
Error: This expression has type int but an expression was expected of type
int list
```

Obs: The reason the second returns an error is because total returns`int`

and`map`

should return a`list`

, that’s why in the first one we passed a`list`

of`lists`

, so for each list`total`

returned an`int`

and the`map`

function returned and`list`

of`ints`

;

Example using anonymous function:

`map (fun x -> x * 2) [1; 2; 3];;`

### Partial Application

We can apply a function passing only some of it’s parameters. For example:

```
let add x y = x + y;;
let add1 = add 1;;
add1 2;;
- : int = 3
```

Let’s use it with our map function:

```
map (add 1) [1; 2; 3];;
- : int list = [2; 3; 4]
```

or let’s use partial application of map function:

```
# map (map (add 1)) [[1; 2]; [3; 4]; [5; 6]];;
- : int list list = [[2; 3]; [4; 5]; [6; 7]]
# map (map total) [[[1; 2]; [1; 2]]; [[1; 2]; [1; 2]]];;
- : int list list = [[3; 3]; [3; 3]]
```

## Tuples

Tuples are ordered collections of elements of different types. For example:

```
- let t = (1, "okay", '1');;
val t : int * string * char = (1, "okay", '1')
```

## Records

They’re similar to tuples, but instead of having elements in a fixed order, they have named elements:

```
type person =
{name: string;
age: int};;
let frank =
{name: "frank";
age: 21};;
let age = frank.age;;
```

## Exceptions

Use `raise`

keyword to throw exceptions, example:

```
let f a b =
if b = 0 then raise (E2 "division by zero") else a / b;;
```

Built-in polymorphic `option`

type:

`type 'a option = None | Some of 'a;;`

We may write:

```
let f a b =
if b = 0 then None else Some (a / b);;
```

## Imperative OCaml

We use `ref`

keyword to create references:

`let r = ref 0;;`

We use `:=`

operator to assign a value to the reference:

`r := 100;;`

We use `!`

operator to de-reference so we can get the reference contents:

```
# !r;;
- : int = 100
```

## Loops

For loop:

```
# let table n =
for row = 1 to n do
for column = 1 to n do
print_string (string_of_int (row * column));
print_string " "
done;
print_newline ()
done;;
val table : int -> unit = <fun>
```

While loop:

```
# let smallest_power_of_two x =
let t = ref 1 in
while !t < x do
t := !t * 2
done;
!t;;
val smallest_power_of_two : int -> int = <fun>
```

## Arrays

OCaml does have arrays, like:

```
# let arr = [|1; 2; 3|];;
val arr : int array = [|1; 2; 3|]
# arr.(0);;
- : int = 1
# arr.(0) <- 0;;
- : unit = ()
# arr;;
- : int array = [|0; 2; 3|]
```

## Standard Libraries

Printf module:

```
let print_length s =
Printf.printf "%s has %i characters\n" s (String.length s);;
```