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.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
3.8. Links
OCaml manual: https://ocaml.org/manual/index.html
OCaml first hour tutorial: https://ocaml.org/learn/tutorials/a_first_hour_with_ocaml.html
A collection of useful cheat sheets: https://github.com/OCamlPro/ocaml-cheat-sheets