### Lists

Lists are immutable. Lists let you hold any number of items of the same type.

```
let l = ["i"; "am"; "list"];;
```

### Tuples

A tuple is an ordered collection of values that can each be of a different type. You can create a tuple by joining values together with a comma.

```
let a_tuple = (3,"three") ;;
val a_tuple : int * string = (3, "three")
let another_tuple = (3,"four",5.) ;;
val another_tuple : int * string * float = (3, "four", 5.)
```

Destructuring of a tuple

```
let (x,y) = a_tuple ;;
(**val x : int = 3
val y : string = "three" *)
```

Adding elements in front of list

```
"French" :: "Spanish" :: languages ;;
(** - : string list = ["French"; "Spanish"; "OCaml"; "Perl"; "C"] *)
```

Concatenation of two lists

```
[1;2;3] @ [4;5;6] ;;
(** - : int list = [1; 2; 3; 4; 5; 6] *)
```

### Records

```
type point2d = { x : float; y : float }
```

Destructuring of the record

```
let magnitude { x = x_pos; y = y_pos } =
Float.sqrt (x_pos **. 2. +. y_pos **. 2.)
;;
(* val magnitude : point2d -> float = <fun> *)
```

Composing records

```
type circle_desc = { center: point2d; radius: float }
type rect_desc = { lower_left: point2d; width: float; height: float }
type segment_desc = { endpoint1: point2d; endpoint2: point2d }
```

Variant types

```
type scene_element =
| Circle of circle_desc
| Rect of rect_desc
| Segment of segment_desc
```

### Arrays

The mutable guy.

```
let numbers = [| 1; 2; 3; 4 |] ;;
(* val numbers : int array = [|1; 2; 3; 4|] *)
numbers.(2) <- 4 ;;
(* - : unit = () )*
numbers ;;
(* - : int array = [|1; 2; 4; 4|] *)
```

The .(i) syntax is used to refer to an element of an array, and the <- syntax is for modification. Because the elements of the array are counted starting at zero, element .(2) is the third element.

What is Unit? Unit it's just a placeholder similar to void in other more mainstream languages

### Mutable records

Records, which are immutable by default, can have some of their fields explicitly declared as mutable. Here’s an example of a mutable data structure for storing a running statistical summary of a collection of numbers.

```
type running_sum =
{ mutable sum: float;
mutable sum_sq: float; (* sum of squares *)
mutable samples: int;
}
```

Let's write some imperative stuff

```
let mean rsum = rsum.sum /. Float.of_int rsum.samples
let stdev rsum =
Float.sqrt (rsum.sum_sq /. Float.of_int rsum.samples
-. (rsum.sum /. Float.of_int rsum.samples) **. 2.)
;;
(* val mean : running_sum -> float = <fun> *)
(* val stdev : running_sum -> float = <fun> *)
let create () = { sum = 0.; sum_sq = 0.; samples = 0 }
let update rsum x =
rsum.samples <- rsum.samples + 1;
rsum.sum <- rsum.sum +. x;
rsum.sum_sq <- rsum.sum_sq +. x *. x
;;
(* val create : unit -> running_sum = <fun> *)
(* val update : running_sum -> float -> unit = <fun> *)
```

Take a look into semicolons to sequence operations. When you are working purely functionally, this wasn’t necessary, but you start needing it when you’re writing imperative code.

```
let rsum = create () ;;
val rsum : running_sum = {sum = 0.; sum_sq = 0.; samples = 0}
List.iter [1.;3.;2.;-7.;4.;5.] ~f:(fun x -> update rsum x) ;;
(* - : unit = () *)
mean rsum ;;
(* - : float = 1.33333333333333326 *)
stdev rsum ;;
(* - : float = 3.94405318873307698 *)
```

### Refs

Ref is a single mutable variable (hi ma react boys)

```
let x = { contents = 0 } ;;
val x : int ref = {contents = 0}
x.contents <- x.contents + 1 ;;
- : unit = ()
x ;;
- : int ref = {contents = 1}
```

Some syntactic sugar for ref

```
let x = ref 0 (* create a ref, i.e., { contents = 0 } *) ;;
(* val x : int ref = {Base.Ref.contents = 0} *)
!x (* get the contents of a ref, i.e., x.contents *) ;;
(* - : int = 0 *)
x := !x + 1 (* assignment, i.e., x.contents <- ... *) ;;
(* - : unit = () *)
!x ;;
(* - : int = 1 *)
```

Nothing magic here, let's implement the ref by ourselves

```
type 'a ref = { mutable contents : 'a } ;;
type 'a ref = { mutable contents : 'a; }
let ref x = { contents = x } ;;
(* val ref : 'a -> 'a ref = <fun> *)
let (!) r = r.contents ;;
(* val ( ! ) : 'a ref -> 'a = <fun> *)
let (:=) r x = r.contents <- x ;;
(* val ( := ) : 'a ref -> 'a -> unit = <fun> *)
```

## Discussion (0)