OCaml for the impatient
The web's quickest and dirtiest OCaml getting started guide
Ocaml is a rad language with some regrettably underdocumented parts. Or, perhaps, overdocumented – since OCaml attracts people who are interested in rigorous correctness, what documentation exists tends to be rigorous and correct, and also tedious. This guide will be none of those. Let’s go!
Install OPAM
This guide will require you to install OCaml and OPAM before we can really do anything. OCaml for obvious reasons, and OPAM because it’s the standard OCaml package manager and is required to install everything else.
I won’t cover how to do that because I just followed the Real World OCaml Installation Instructions and it seemed to do fine. If you get OPAM installed and working, you should be able to move on to the next step.
Choose an OCaml version
It is strongly recommended that you pick an OCaml version that your project will compile against. You can do that
using the opam switch
. First, run the following to list all the versions available (your output may differ):
$ opam switch list
-- -- 3.07 Official 3.07 release
-- -- 3.08.0 Official 3.08.0 release
-- -- 3.08.1 Official 3.08.1 release
-- -- 3.08.2 Official 3.08.2 release
-- -- 3.08.3 Official 3.08.3 release
-- -- 3.08.4 Official 3.08.4 release
-- -- 3.09.0 Official 3.09.0 release
-- -- 3.09.1 Official 3.09.1 release
-- -- 3.09.2 Official 3.09.2 release
-- -- 3.09.3 Official 3.09.3 release
-- -- 3.10.0 Official 3.10.0 release
-- -- 3.10.1 Official 3.10.1 release
-- -- 3.10.2 Official 3.10.2 release
-- -- 3.11.0 Official 3.11.0 release
-- -- 3.11.1 Official 3.11.1 release
-- -- 3.11.2 Official 3.11.2 release
-- -- 3.12.0 Official 3.12.0 release
-- -- 3.12.1 Official 3.12.1 release
-- -- 4.00.0 Official 4.00.0 release
-- -- 4.00.1 Official 4.00.1 release
-- -- 4.01.0 Official 4.01.0 release
-- -- 4.02.0 Official 4.02.0 release
-- -- 4.02.1 Official 4.02.1 release
-- -- 4.02.2 Official 4.02.2 release
-- -- 4.02.3 Official 4.02.3 release
-- -- 4.03.0 Official 4.03.0 release
-- -- 4.04.0 Official 4.04.0 release
-- -- 4.04.1 Official 4.04.1 release
-- -- 4.04.2 Official 4.04.2 release
4.05.0 C 4.05.0 Official 4.05.0 release
system I system System compiler (4.05.0)
# 250 more patched or experimental compilers, use '--all' to show
Pick the most recent one and pin yourself to that, then activate your configuration (the opam switch command output will remind you to do this):
$ opam switch 4.05.0
$ eval `opam config env`
The first time you run opam switch
for a version you don’t have installed, it will download, compile, and install that version.
Creating your Project directory
The first thing you need to do is to create a project directory. I’ll be calling my project “ocamltestproj”; keep that in mind, it’ll be relevant later:
$ mkdir ~/Projects/ocamltestproj
$ cd ~/Projects/ocamltestproj
Next you need to add at least one .ml source file to the folder. This is important, and if you’re used to other
languages that demand setup before you start coding you might miss it (I did). So far, I’ve been organizing code
into two directories: bin/
and lib/
. So, make those two directories now:
$ mkdir bin
$ mkdir lib
Finally, we’ll get a source file in. Create a file named bin/main.ml
, and add the following to it:
let () =
print_endline "Hello World"
In this configuration, the files in bin
will have access to those in lib
, via Lib.<module>
(e.g., if you have
a source file named lib/test.ml
, you can refer to it in bin/main.ml
via Lib.Test
.
Add your project to OPAM
Next, we’ll add your project to your local OPAM repository so we can use OPAM to install its dependencies.
Run the following command to create your project and instantiate an opam
file for it. Note that it will
prompt you to edit the OPAM file; feel free to save your invalid opam file, you can always run opam lint
later.
$ opam pin add ocamltestproj . -n ──(Mon,Aug28)─┘
After this is done, rename the opam
file to include your project name:
$ mv opam ocamltestproj.opam
Set up jbuilder
You can install merlin and jbuilder as easy as:
$ opam install merlin jbuilder
Setting up jbuilder entails creating a jbuild
file for each source directory. In bin/jbuild
put the following
to denote the program’s executable (jbuild config is some sort of lisp, so anything followed by ;
is a comment):
(jbuild_version 1)
(executable
((name main) ; The name of your entry file, minus the .ml
(public_name OcamlTestProj) ; Whatever you like, as far as I can tell
(libraries (lib)))) ; Express a dependency on the "lib" module
In lib/jbuild
, put the following:
(jbuild_version 1)
(library
((name lib)
(libraries ())))
Notice the empty “libraries” declaration, we’ll come back here.
Now, you should be able to run jbuilder build
from the root of your directory. If this succeeds, you will find
a new _build
directory in your project root. You should be able to run your program like so:
$ ./_build/default/bin/main.exe
Hello World
You will also find a .merlin
file in each source directory with a .ml file in it. This will tell merlin about your
source files and dependencies and in general let it work properly.
Adding a dependency
At very least, just about every ocaml program will want to include the “core” library, which is essentially ocaml’s standard library.
First, install it via opam
:
$ opam install core
Then, add it to lib/jbuild
:
(jbuild_version 1)
(library
((name lib)
(libraries (core))))
Now you can use Core in your project! Since bin/
depends directly on lib/
, it has access to the library too.
Update bin/main.ml
to use it:
open Core
let () =
print_endline "Hello World"
Next, run jbuilder build
. Your project should build successfully
(importantly, this also adds the new dependency to the .merlin files).
You can repeat this process any time you need a new dependency.
Congratulations! You should have all you need to get started.
Bonus section: Setting up VSCode for OCaml development
Thanks to Merlin, just about any code editor can field a decent OCaml integration. I like VSCode’s because it works almost out of the box (and because the Vim plugin actually uses Neovim under the hood).
Just open VSCode and search for and install the OCaml extension (package: hackwaly.ocaml). Since JBuilder handles the .merlin
files for you, you should
have rich autocompletion and linting out of the box. Next, you can open your project root.
You can also configure your build command to use jbuilder. Just create a file called .vscode/tasks.json
in your project root and put the following in it:
{
"version": "2.0.0",
"tasks": [
{
"taskName": "build",
"type": "shell",
"command": "jbuilder build",
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
Now, pressing command+shift+B (or whatever the windows equivalent is) will build with jbuilder automatically. Remember that jbuilder generates your .merlin files, so you’ll want to rebuild whenever you add a dependency.
Now you should have all you need to start poking around OCaml. I, like everyone, recommend using Real World OCaml as a guide.