# Functional programming in OCaml

## ▸Introduction

### About the course

Intended for functional beginners already familiar with some programming language.

#### Goals

If all goes well, by the end of this course, you shall be able to:

- Understand lambda-terms and write pure functional programs.
- Design recursive functions to iterate over recursive data types.
- Wonder how you have survived so far without algebraic data types and parameterized types.
- Think in terms of higher-order functions in order to write reusable code.
- Astonish yourself by writing polymorphic functions without even noticing.

#### Evaluation

The exam is on october, 12th: a list of exercises, on computer.

### Setup

- To use OCaml at INSA, copy to your homedir /mnt/commetud/GEI/OCaml/.profile and read it.
- Open a new terminal and launch utop: `utop`
  You should get a nice greeting message. Press CTRL+D to quit.
- Alternatively, you can write small OCaml programs directly on Try OCaml.

## ▸Programming assignments (lessons)

Each lesson must be worked individually, and completed before starting the next one.

#### Answers

- Lesson 1: lesson1.ml
- Lesson 2: lesson2.ml
- Lesson 3: lesson3.ml
- Lesson 4: lesson4.ml
- Lesson 5: lesson5.ml
- Lesson 6: lesson6.ml

Some solutions might be out of date, or unclear—
signal them to Mr. Le Botlan, then.

- Lesson 1The ocaml interpreter, ground types, built-in types.
- Lesson 2Functions, curryfication.
- Lesson 3Pattern matching, inner let.
- Lesson 4Type structures.
- Lesson 5Algorithms and more type structures
- Lesson 6Compilation, exceptions, side effects.

#### For the curious, some complementary information

- Facebook's REASON, or how to program in OCaml while pretending to write Javascript.
- Xavier Leroy, proficient developper of the Ocaml compiler, tells how he ran into a bug in some Intel processors.
- Watch 👁Tail-call recursion, the musical, which explains how call-stacks work.
- Learn why OCaml's Garbage collector is efficient.

## ▸Exam-type exercises

#### Answers

- Ex. 1: exo1.ml
- Ex. 2: exo2.ml
- Ex. 3: exo3.ml

- Exam questions are only intended to test your skills. They are not intended to be smart or enlightening. Thus, do not get surprised if examples are totally unmeaningful.
- You do not have to write tail-recursive functions, unless explicitly required.

- Ex. 1Basic types, curried functions, polymorphism, pattern matching
- Ex. 2Lists, records, variants.
- Ex. 3Recursive structures, exceptions
- Ex. 99A list of 99 problems of various difficulty. (Some of them are easier than the exam, some are harder.)
- Ex. 2017Exam questions, 2017.
- Ex. 2019Exam questions, 2019.
- Ex. 2020Exam questions, 2020.

#### Get prepared for the exam:

The following works only on INSA computers (purposely).

- You must have configured your account to use ocaml (see Setup above)
- In a terminal, launch `/mnt/commetud/GEI/run-exam &`
- Choose the OCaml Test Exam. The expected password is `exam`
- This test exam contains two easy questions.

## ▸Project

The project is to be done by pairs of students having the same level.

#### Requirements

➪ You have completed all the lessons, and know how to write OCaml Modules.

#### How it goes

- The goal is to implement an algorithm computing the max-flow of a flow graph, using the Ford–Fulkerson algorithm, and optionally improve it to take into account other constraints (e.g. minimize cost).
  See the details of the project.
- You are free to propose another project, by considering another graph algorithm — check with the teacher.

#### Evaluation

- Before december, 12th, you have to send to your teacher (D. Le Botlan or A. Bit-Monnot) a link to your github project (or any other similar repository).
- Manage to meet your teacher and show him a very quick demo (2 minutes). He will then ask you questions about your project (5-10 minutes).

The final grade takes into account:

- your achievements (how much is in your project)
- your code's modularity (do you use modules, abstract types?)
- the level of abstraction and genericity (do you take advantage of polymorphism, parameterized types?)
- code quality (comments, conciseness)
- your answers to questions during the quick demo

## ▸Getting help

### Resources

- Many resources about OCaml: //ocaml.org/
- Books to learn OCaml.
- The very official OCaml manual.
- A well-written french book about functional programming (Bib'INSA):
  Mini Manuel de Programmation Fonctionnelle—Éric Violard—DUNOD 978-2-10-070385-2
- OCamlverse : some documentation about OCaml.

### OCaml at home

- See how to install.
  The recommended way is OPAM on linux.
- Install packages text, utop and ocaml-top.
- On windows, see how to install ocaml-top. (Have you considered switching to a decent, free OS ?)

##### A stupid separator, because flex sucks in css.

### ▸Trouble?

#### Packages

- If you need to use a package, e.g. `text` in an interpreter, you must start your program as follows:
  `#use "topfind" ;; (* Done once *) #require "text" ;; (* For every package you need. *)`

#### Pitfalls

- Sequence: when writing a sequence, do not put a `;` on the last statement.
  `let f () = Printf.printf "Meet" ; Printf.printf "John" ; Printf.printf "Doe" ; let g x = x + 1 (* Error detected here. *) let h x = x - 1`
  - An error is detected at the end of the definition of g.
  - It is difficult to understand why the error appears there (try to find out).
  - The real error is the extra `;` at the end of f (after "Doe").
  To avoid this problem, always finish a sequence with unit (and no semicolumn), in order to mark clearly the end of the sequence:
  `let f () = Printf.printf "Meet" ; Printf.printf "John" ; Printf.printf "Doe" ; () let g x = x + 1 (* No error. *) let h x = x - 1`
- Nested pattern-matching: be careful when a `match` occurs inside another pattern-matching:
  `(* This (curried) function expects two arguments. *) let f x = function | 0 -> false | 1 -> match x with | 0 -> false | 1 -> true | 2 -> true | _ -> false`
  It does not behave as you think. If you auto-indent the code, you get the real meaning:
  `let f x = function | 0 -> false | 1 -> match x with | 0 -> false | 1 -> true | 2 -> true | _ -> false`
  To fix it, use `begin`...`end` or parentheses:
  `let f x = function | 0 -> false | 1 -> begin match x with | 0 -> false | 1 -> true end | 2 -> true | _ -> false`
  When a match is nested in another pattern-matching, it is good practice to put `begin`...`end` around it.

### Tutorials

- What I wish I knew when learning OCaml.
- Local variables (`let .. in ..`)
- Getting your feet wet with OCaml (how to gently install and discover OCaml).
- Le MOOC OCaml (démarre en septembre 2019)

❯ contact.lebotlan ❅ insa-toulouse.fr ❮