*Due date: Tuesday, September 10th, 11:59PM*

In this course, we use OCaml for most programming assignments. This tutorial only covers the tiny sliver of OCaml you truly need to do the assignments. The course also uses tools and testing extensions that are not part of the standard OCaml distribution; this tutorial introduces them too.

The tutorial is divided into several sections. Each section introduces new OCaml features, provides some examples, and concludes with exercises that you should do. The solutions to all exercises are provided, but you should try to do the exercises before you click "show solution".

OCaml is a sophisticated programming language with several advanced features. We encourage you to explore OCaml on your own. There are several other tutorials and guides on the Ocaml Website. Real World OCaml is an excellent book that covers the language and programming pragmatics in depth.

**Prerequisite:** You must install the course
software, which includes OCaml to do this tutorial. Do ask for help
if you have trouble installing the software.

A simple OCaml program is a sequence of *declarations*, followed by
a *main expression*. You must use a double-semicolon (`;;`

)
to separate the declarations from the main expression. E.g.:

```
let x : int = 23
let y : int = 60
let sum : int = x + y
let message : string = "The sum is " ^ string_of_int sum ^ ".\n"
;;
print_string message
```

In this example, all the declarations are *let declarations*.
(We introduce a few other kinds of declarations momentarily.) A let
declaration states the name of the bound identifier, its type, and the bound
expression. Unlike more complex languages, OCaml does not automatically
convert between values of different types. For example, the code above
explicitly applies string_of_int . Without
this conversion, the OCaml compiler woudl fail with a type error:

This expression has type int but an expression was expected of type string.

Similarly, OCaml has no function or operator overloading. In many languages,
`x + y`

may mean "add two numbers" or "concatenate two strings".
In OCaml these two operations are distinct: `x ^ y`

means string
concatenation and `x + y`

means integer addition. Incidentally,
`x +. y`

means floating point addition.

In OCaml, we can declare functions using a variation of let declarations:

```
let increment (a : int) : int =
a + 1
let add_three (x : int) (y : int) (z : int) : int =
x + y + z
let make_message (n : int) : string =
"The sum is " ^ string_of_int n ^ ".\n"
;;
print_string (make_message (add_three 1 2 3))
```

In these declarations, each function argument has a name and type enclosed in parentheses. The final type in the declaration is the type of the function result.

Pay close attention to the syntax of function application in the main expression. A function application uses spaces to separate the function from each argument. The parentheses simply ensure that arguments are properly grouped. For example, suppose we missed the inner parentheses and wrote:

`print_string (make_message add_three 1 2 3)`

This expression applies `make_message`

to four arguments, but
it expects only one, so we have a type error. Similarly, suppose
we missed the outer parentheses:

`print_string make_message (add_three 1 2 3)`

This expression applies `print_string`

to two arguments, but
it expects only one, so we have another type error. When it doubt, use
parentheses for clarity.

In OCaml, `let`

does not introduce a recursive binding.
Therefore, to declare a recursive function, we must use`let rec`

instead:

```
let rec factorial (n : int) : int =
if n = 0 then
1
else
n * factorial (n - 1)
;;
print_string ("factorial 5 = " ^ string_of_int (factorial 5) ^ "\n")
```

Printing strings in this manner is a very poor way to test code. You'll do better by writing test cases as follows:

```
TEST "testing factorial 5" =
factorial 5 = 120
TEST "testing factorial 8" =
factorial 8 = 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8
```

The `TEST`

notation is not standard OCaml, but a handy syntax extension
that we use extensively in this course. The course software will take
care of linking to the syntax extension for you.

For this course, you should use the `cs691f`

build tool to
compile programs and run tests. This program is a thin wrapper around the
OCaml's own build system that links to libraries and extensions
that we use in this course. If you want to look under the hood, the code
is
online
and in OCaml.

Place the declaration of factorial and its test cases, all of which
appear above, in a new file called *tutorial.ml*. Then, compile, run,
and test using the `cs691f`

tool:

$ cs691f compile tutorial $ cs691f run tutorial $ cs691f test tutorial

You should not get any errors.

Write a function, `seconds_since_midnight h m s`

, which returns
the number of seconds elapsed since midnight. Your function should have the
following type.

`val seconds_since_midnight : int -> int -> int -> int`

```
let seconds_since_midnight (hours : int) (mins : int) (secs : int) : int =
secs + 60 * (mins + 60 * hours)
TEST "midnight" = seconds_since_midnight 0 0 0 = 0
TEST "12:59:59PM" = seconds_since_midnight 23 59 59 = 86399
TEST "1:30AM" = seconds_since_midnight 1 30 0 = 3600 + 30 * 60
```

Write a function, `fibonacci n`

, which compute the *n*th
Fibonacci number. The function should have the following type:

`val fibonacci : int -> int`

```
let rec fibonacci n =
if n = 0 then
0
else if n = 1 then
1
else fibonacci (n - 1) + fibonacci (n - 2)
TEST "fib 2" =
fibonacci 2 = 1
TEST "fib 7" =
fibonacci 7 = 13
```

The previous section covered let declarations. This section introduces
*type declarations*. Here is an example:

```
type point =
Point2D of int * int
```

This type declaration introduces a type called `point`

. It has one
*constructor* called `Point2D`

that takes two arguments, both
integers. Type names must begin with a lowercase letter and constructor names must
begin with an uppercase letter.

Given this declaration, we can use the constructor to create new points:

```
let origin : point = Point2D (0, 0)
let pt1 : point = Point2D (10, 20)
let pt2 : point = Point2D (-40, 50)
```

Above, the parentheses and commas are required: the constructor name must be followed by a comma-separated list of arguments enclosed in parentheses.

Define a type, `time`

, which holds the hour, minute,
and second as separate values.

`type time = Time of int * int * int`

Given a point value, we can use *pattern matching* to extract
its components, as these functions do:

```
let double_point (p : point) : point =
match p with
Point2D (x, y) -> Point2D (2 * x, 2 * y)
let add_point (p1 : point) (p2 : point) : point =
match (p1, p2) with
(Point2D (x1, y1), Point2D (x2, y2)) -> Point2D (x1 + x2, y1 + y2)
let string_of_point (p : point) : string =
match p with
Point2D (x, y) -> "<" ^ string_of_int x ^ ", " ^ string_of_int y ^ ">"
```

In the following several exercises, you will use pattern matching to write functions that manipulate points. The OCaml manual has a section on integer arithmetic that will be helpful.

Write a function `seconds_since_midnight2`

with the
following type:

`val seconds_since_midnight2 : time -> int`

```
let seconds_since_midnight2 (t : time) : int =
match t with
| Time (hours, mins, secs) -> secs + 60 * (mins + 60 * hours)
```

Write a function `seconds_to_time t`

, which takes the seconds
elapsed since midnight as its argument and returns the coresponding time.

`val seconds_to_time : int -> time`

```
let seconds_to_time (n : int) : time =
let secs = n mod 60 in
let n = (n - secs) / 60 in
let mins = n mod 60 in
let n = (n - secs) / 60 in
let hours = n in
Time (hours, mins, secs)
TEST = seconds_to_time 0 = Time (0, 0, 0)
TEST = seconds_to_time 86399 = Time (23, 59, 59)
TEST = seconds_to_time 86400 = Time (24, 0, 0)
```

Write a function `time_diff t1 t2`

, which calculates
the number of seconds that have elapsed between `t1`

and
`t2`

:

`val time_diff : time -> time -> int`

```
let time_diff (t1 : time) (t2 : time) : int =
seconds_since_midnight2 t1 - seconds_since_midnight2 t2
TEST = let t = Time (1, 1, 1) in time_diff t t = 0
TEST = time_diff (Time (23, 59, 59)) (Time (0, 0, 0)) = 86399
```

Write a function `tick t`

, which increments `t`

by
one second and returns the new time:

`val tick : time -> time`

```
let tick (t : time) : time =
seconds_to_time (1 + seconds_since_midnight2 t)
TEST = tick (Time (0, 0, 59)) = Time (0, 1, 0)
TEST = tick (Time (1, 59, 59)) = Time (2, 0, 0)
TEST = tick (Time (23, 59, 59)) = Time (24, 0, 0)
```

For this part of the tutorial, we will work with a type declaration for lists of integers. There are two kinds of lists: the empty list and lists that have a single integer and a a reference to the rest of the list. We can specify the shape of lists using a type declaration with two constructors:

```
type intlist =
| Cons of int * intlist
| Empty
```

For example, here is a list of numbers from -1 through 4:

```
let from_minus_1_to_4 =
Cons (-1, Cons (0, Cons (1, Cons (2, Cons (3, (Cons (4, Empty)))))))
```

We can declare list processing functions using the same constructs we used to write date processing functions. However, since lists are recursively defined, most interesting list processing functions need to be recursive, too. For example, here is a function that calcululates the length of a list:

```
let rec length (lst : intlist) : int =
match lst with
| Empty -> 0
| Cons (first, rest) -> 1 + length rest
TEST = length Empty = 0
TEST = length from_minus_1_to_4 = 6
```

Write a function `all_positive lst`

, which returns `true`

if all the integers in `lst`

are positive.

`val all_positive : intlist -> bool`

```
let rec all_positive (lst : intlist) : bool =
match lst with
| Empty -> true
| Cons (n, rest) -> n > 0 && all_positive rest
TEST = all_positive (Cons (1, Empty)) = true
TEST = all_positive (Cons (-1, Empty)) = false
TEST = all_positive (Cons (1, Cons (-1, Empty))) = false
```

Write a function `all_even lst`

, which returns `true`

if all the integers in `lst`

are even numbers.

`val all_even : intlist -> bool`

```
let rec all_even (lst : intlist) : bool =
match lst with
| Empty -> true
| Cons (n, rest) -> n mod 2 = 0 && all_even rest
TEST = all_even (Cons (10, (Cons (2, Empty)))) = true
TEST = all_even (Cons (9, (Cons (1, Empty)))) = false
TEST = all_even Empty = true
```

Write the function `is_sorted lst`

to determine if the
integers in `lst`

are in sorted (ascending).

`val is_sorted : intlist -> bool`

*Hint:* You will need to write a recursive helper function.

```
let rec is_sorted_helper (prev : int) (lst : intlist) : bool =
match lst with
| Empty -> true
| Cons (n, rest) -> prev <= n && is_sorted_helper n rest
let is_sorted (lst : intlist) : bool =
match lst with
| Empty -> true
| Cons (n, rest) -> is_sorted_helper n rest
TEST = is_sorted (Cons (1, Cons (2, Cons (3, Empty)))) = true
TEST = is_sorted (Cons (1, Cons (1, Cons (3, Empty)))) = true
TEST = is_sorted (Cons (1, Cons (3, Cons (2, Empty)))) = false
```

Write the function `insert_sorted n lst`

, which inserts
`n`

into the sorted list `lst`

and preserves the
sort-order.

```
(* Assumes that [is_sorted lst] holds. *)
let rec insert_sorted (n : int) (lst : intlist) : intlist =
match lst with
| Empty -> Cons (n, Empty)
| Cons (m, rest) ->
(match n <= m with
| true -> Cons (n, Cons (m, rest))
| false -> Cons (m, insert_sorted n rest))
TEST = insert_sorted 5 Empty = Cons (5, Empty)
TEST =
insert_sorted 1 (Cons (0, Cons (2, Empty))) =
Cons (0, Cons (1, Cons (2, Empty)))
TEST = insert_sorted 10 (Cons (10, Empty)) = Cons (10, Cons (10, Empty))
```

Write the `insertion_sort`

function, using
`insert_sorted`

as a helper.

`val insertion_sort : intlist -> intlist`

```
let rec insertion_sort (lst : intlist) : intlist =
match lst with
| Empty -> Empty
| Cons (n, rest) -> insert_sorted n (insertion_sort rest)
TEST = insertion_sort (Cons (3, Cons (2, Cons (1, Empty)))) =
Cons (1, Cons (2, Cons (3, Empty)))
```

For this part of the tutorial, you will write an evaluator and pretty-printer for simple arithmetic expressionsâ€”the simplest of interpreters. Notably, this interpreter does not use any OCaml concept beyond those introduced above.

For the exercises below, use the following type declaration that represents arithmetic expressions.

```
type exp =
| Int of int
| Add of exp * exp
| Mul of exp * exp
```

Encode the following arithmetic expressions as `exp`

s:

- 10 + 5
- (2 + 3) * 5
- 3 * 0 * 3 * 5

```
let ex1 = Add (Int 10, Int 5)
let ex2 = Mul (Add (Int 2, Int 3), Int 5)
let ex3 = Mul ((Mul (Int 3, Int 0)), Mul (Int 3, Int 5))
```

Write the function `eval e`

, which reduces expressions to
integer values:

`val eval : exp -> int`

```
let rec eval (e : exp) : int = match e with
| Int n -> n
| Add (e1, e2) -> eval e1 + eval e2
| Mul (e1, e2) -> eval e1 * eval e2
TEST = eval (Add (Int 10, Int 5)) = 15
TEST = eval (Mul (Add (Int 2, Int 3), Int 5)) = (2 + 3) * 5
TEST = eval (Mul ((Mul (Int 3, Int 0)), Mul (Int 3, Int 5))) = 0
```

Write the function `print e`

, which returns a string
representing `e`

:

`val print : exp -> string`

The string should print arithmetic operators using infix notation and properly parenthesize expressions. For example, here are some tests:

```
TEST = print (Add (Int 10, Int 5)) = "(10 + 5)"
TEST = print (Mul (Add (Int 2, Int 3), Int 5)) = "((2 + 3) * 5)"
TEST = print (Mul ((Mul (Int 3, Int 0)), Mul (Int 3, Int 5))) = "((3 * 0) * (3 * 5))"
```

Use the ^ operator to concatenate strings and the string_of_int function.

```
let rec print (e : exp) : string = match e with
| Int n -> string_of_int n
| Add (e1, e2) -> "(" ^ print e1 ^ " + " ^ print e2 ^ ")"
| Mul (e1, e2) -> "(" ^ print e1 ^ " * " ^ print e2 ^ ")"
```

The `print`

function that you wrote above may be naive
about how it prints parentheses. For example, `1 + 2 * 3`

is usually interpreted as `1 + (2 * 3)`

because the `*`

operator `+`

operator.
Write the `pretty_print e`

function, which prints parentheses
only when necessary:

`val pretty_print : exp -> string`

`pp cxt e`

,
where `e`

is the expression to print and `cxt`

identifies
the shape of the immediately surrounding context.

```
type cxt =
| TopCxt (* top-level expression *)
| MulCxt (* [_ * x] or [x * _] *)
| AddCxt (* [_ + x] or [x + _] *)
let rec pp (enclosing : cxt) (e : exp) : string =
match e with
| Int n -> string_of_int n
| Add (e1, e2) ->
let inner = (pp AddCxt e1) ^ " + " ^ (pp AddCxt e2) in
(match enclosing with
| MulCxt -> "(" ^ inner ^ ")"
| _ -> inner)
| Mul (e1, e2) ->
(pp MulCxt e1) ^ " * " ^ (pp MulCxt e2)
let pretty_print (e : exp) : string = pp TopCxt e
TEST = pretty_print (Add (Int 10, Int 5)) = "10 + 5"
TEST = pretty_print (Mul (Add (Int 2, Int 3), Int 5)) = "(2 + 3) * 5"
TEST =
pretty_print (Mul ((Mul (Int 3, Int 0)), Mul (Int 3, Int 5))) = "3 * 0 * 3 * 5"
```