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.

OCaml Installation
^^^^^^^^^^^^^^^^^^
TODO

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.

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,

.. code-block::

   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

.. code-block::

   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.

.. code-block::

   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:

.. code-block::

   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:

.. code-block::

   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:

.. code-block::

   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.

.. code-block::

   S src/**
   B src/**

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

Installation for Emacs
""""""""""""""""""""""

.. code-block::

   opam install merlin
   opam user-setup install


TODO Configuration


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:

.. code-block:: OCaml

   let add a b = a + b

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

.. code-block:: OCaml

   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:

.. code-block:: OCaml

   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:

.. code-block:: OCaml

   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:

.. code-block:: OCaml

   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:

.. code-block:: OCaml

   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.


Data Types
^^^^^^^^^^
TODO


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.


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:

.. code-block:: OCaml

   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``.


Imperative Concepts and Object Orientation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TODO


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