3. Ocaml Primer

OCaml is a functional programming language with object oriented and imperative features. BINSEC and CODEX are both written mostly in OCaml. This page should give a quick overview over the language and its basic features.

3.1. OCaml Installation

TODO

3.2. Merlin

Merlin is a plugin for editors to give IDE-like features for OCaml projects. This includes for example syntax highlighting, error reporting or auto-completion.

This section documents the installation and configuration for various editors.

3.2.1. Installation for VSCodium

Merlin is available as a plugin for Microsofts Visual Studio Code, under the name OCaml-Platform.

To install the free licensed and unbranded version of VSCode, VSCodium on Debian-based distributions add the developers keys,

wget -qO - https://gitlab.com/paulcarroty/vscodium-deb-rpm-repo/raw/master/pub.gpg \
 | gpg --dearmor \
 | sudo dd of=/usr/share/keyrings/vscodium-archive-keyring.gpg

add the repository

echo 'deb [ signed-by=/usr/share/keyrings/vscodium-archive-keyring.gpg ] https://paulcarroty.gitlab.io/vscodium-deb-rpm-repo/debs vscodium main' \
 | sudo tee /etc/apt/sources.list.d/vscodium.list

and install the deb package with apt.

sudo apt update && sudo apt install codium

To install the plugin in VSCodium press Ctrl+Shift+P to open the VSCodium command prompt and enter:

ext install ocamllabs.ocaml-platform

After that a OCaml project can be imported to VSCodium with File > Add Folder to Workspace....

Additionally a LSP Server needs to be installed with:

opam install ocaml-lsp-server

Merlin needs the compiled .cmi files to work properly. Those can be generated from the .mli header files with ocamlc -c foo.mli.

Note

With Binsec a manual compilation is needed to generate these files:

autoconf
./configure
make -C src depend
make -C src WARN_ERROR=no

To get the definitions of files located in sub directories a .merlin file is needed in the root directory of the project. In this files the source and build directories of the project are defined.

S src/**
B src/**

With this file all sub directories are defined as source and build directories.

3.2.2. Installation for Emacs

opam install merlin
opam user-setup install

TODO Configuration

3.3. Functions

A function definition starts with the key word let followed by the name of the function and the function parameters. The function body starts after a = symbol:

let add a b = a + b

A function is simply applied by writing the function name followed by arguments:

add 17 4
(* Function returns:
   - : int = 21     *)

There are only block comments in OCaml and they start with (* and are closed with *).

The parameters of a function can also be labeled by the ~ prefix, which allows the the application of parameters explicitly by their name:

let add2 ~a ~b = a + b

add2 ~b:1 ~a:2

Optional parameters are stated with the ? prefix.

For a function to be recursive it has to be defined with the key word let rec. For example:

let rec fac n =
  if   n = 0
  then 1
  else n * fac(n-1)

This defines recursively the factorial function and also uses the if ... then ... else statement.

Alternatively the function can also be defined solely by pattern matching with the function key word:

let rec fac2 = function
  | 0 -> 1
  | n -> n * fac(n-1)

Each | introduces a new pattern rule which has a pattern on the left hand side followed by a -> symbol and a right hand side defining the output of the function.

Pattern matching can also be introduced with the match statement:

let f c = match c with
  | 'a' -> 1
  |  _  -> 2

This function returns for a char c an integer. For the 'a' case 1 is returned and for every other case, denoted by the _ default pattern, 2 is returned.

3.4. Data Types

TODO

3.5. Type System

OCaml is a statically typed, which means that the types are known at compile time. Unlike languages like C the types are inferred, so they don’t have to be stated explicitly. For example the type of the function let add a b = a + b is inferred to val add : int -> int -> int = <fun>. Which means that the function takes two int parameters and returns an int. This works without stating the types of the parameters a and b. Because the + operator which is defined for int types is used in the function definition, the type of the function can be inferred.

3.6. Modules

For a OCaml .ml file the module with the capitalized version of the file name is implicitly defined. For example the file test.ml defines automatically the module Test.

A new module M can be defined like that:

module M =
  struct
    (* some code inside the module*)
  end

To access definitions inside the module from the outside the usual . notation is used. The hole module can be includes with include M.

3.7. Imperative Concepts and Object Orientation

TODO