These instructions are aimed at readers of Real World OCaml, though much of what you find here will be useful for anyone who wants to get a good working OCaml installation.
At the highest level, here's what you need to do:
- Get OPAM installed
- Build OCaml 4.06.0 or later using OPAM or your OS package manager
- With OPAM, install the key libraries that you need to work through the examples in the book
- Install Utop, a modern interactive toplevel with command history, tab completion, and defaults that are tuned to work with the examples in Real World OCaml,
- Set up your editing environment.
- Optionally install merlin, a tool for providing IDE-like functionality like auto-completion, as well as ocp-indent, a source code indenter. Both work with emacs and vim, and can be adapted to other editors.
Note that Windows is not currently supported by the examples in Real World OCaml or by OPAM, although it is being worked on. Until that's ready, we recommend using a virtual machine running Debian Linux on your local machine, or Docker for Windows.
Let's get started.
The easiest way to install OPAM is through your OS's package manager. In most cases, installing OPAM will also trigger the installation of OCaml. The version installed isn't important, since we can use OPAM itself to install other versions of the compiler.
Here are platform-specific instructions.
Mac OS X
If you don't already have a package manager set up, try installing homebrew. You can find information on installing homebrew here. make sure you have the latest XCode (and Command Line Tools for XCode) installed from the App Store first.
You can then install OPAM using brew.
brew install opam
Another popular package manager on Mac OS X is MacPorts, which also has an OPAM package.
sudo port install opam
14.04 and higher comes with recent versions of OCaml and opam. No PPA needed.
sudo apt-get install curl build-essential m4 zlib1g-dev libssl-dev ocaml ocaml-native-compilers opam
Debian's OCaml packages aren't yet at 4.06.0, and so you will
need to compile it from sources. If you are using the
stable stream, then OPAM 1.2.2 will
OPAM is available from the AUR (Arch User Repository). You can
install OPAM using
sudo yaourt -S opam
Or directly using
sudo pacman -S base-devel wget https://aur.archlinux.org/packages/op/opam/opam.tar.gz tar -xvf opam.tar.gz && cd opam makepkg sudo pacman -U opam-<version>.pkg.tar.xz
Building from source
On platforms not listed above, you'll need to install OPAM from source, and to do that you'll need OCaml installed first. Some platforms, including Fedora Linux, have OCaml packages that you can install but not OPAM packages. You can build OPAM on OCaml version 4.02.1 or later.
To install OCaml from source, you'll first need a C compiler,
The following is enough to get OCaml installed on most platforms.
curl -OL https://github.com/ocaml/ocaml/archive/4.01.tar.gz tar -zxvf 4.01.tar.gz cd ocaml-4.01 ./configure make world world.opt sudo make install
If you have problems with any of the above, read the
INSTALL file in the tar file.
Installing OCaml locally
The installation step described above requires administrator
privileges. You can also install it in your home directory by
prefix option to the configuration
./configure -prefix $HOME/my-ocaml
Once the installation is completed into this custom location,
you will need to add
$HOME/my-ocaml/bin to your
PATH, normally by editing
~/.profile. You shouldn't really do this unless you
have special reasons, so try to install binary packages before
trying a source installation.
If the binary packages aren't available for your system, you'll need to install the latest OPAM release from source. You can follow the online quick install guide.
The entire OPAM package database is held in the
.opam directory in your home directory, including
compiler installations. On Linux and Mac OS X, this will be the
~/.opam directory, which means you don't need
administrative privileges to configure it. If you run into
problems configuring OPAM, just delete the whole
~/.opam directory and start over.
Let's begin by initialising the OPAM package database. This will ask you a few interactive questions at the end. It's safe to answer yes to these unless you want to manually control the configuration steps yourself as an advanced user.
opam init <...> =-=-=-= Configuring OPAM =-=-=-= Do you want to update your configuration to use OPAM ? [Y/n] y [1/4] Do you want to update your shell configuration file ? [default: ~/.profile] y [2/4] Do you want to update your ~/.ocamlinit ? [Y/n] y [3/4] Do you want to install the auto-complete scripts ? [Y/n] y [4/4] Do you want to install the `opam-switch-eval` script ? [Y/n] y User configuration: ~/.ocamlinit is already up-to-date. ~/.profile is already up-to-date. Gloabal configuration: Updating <root>/opam-init/init.sh auto-completion : [true] opam-switch-eval: [true] Updating <root>/opam-init/init.zsh auto-completion : [true] opam-switch-eval: [true] Updating <root>/opam-init/init.csh auto-completion : [true] opam-switch-eval: [true]
You only need to run this command once, and it will create the
~/.opam directory and sync with the latest package
list from the online OPAM database.
init command finishes, you'll see some
instructions about environment variables. OPAM never installs
files into your system directories (which would require
administrator privileges). Instead, it puts them into your home
directory by default, and can output a set of shell commands
which configures your shell with the right
variables so that packages will just work.
If you choose not to follow the OPAM instructions to add itself to your shell profile, you can still configure it on-the-fly in your current shell with just one command.
eval `opam config env`
This evaluates the results of running
env in your current shell and sets the variables so that
subsequent commands will use them. This only works with
your current shell and it can only be automated for future shells
by adding the line to your login scripts. On Mac OS X you should
on most Linux setups.
OPAM isn't unusual in this approach; the SSH
ssh-agent also works similarly, so if you're having
any problems just hunt around in your configuration scripts to
see how that's being invoked.
If you answered
yes to the auto-complete scripts
opam init, this should have all been
set up for you. You can verify this worked by seeing if the
OCAML_TOPLEVEL_PATH environment variable is set. You
can do this in
bash as follows.
printenv OCAML_TOPLEVEL_PATH /Users/myusername/.opam/4.06.0/lib/toplevel
The next step is to make sure we have the right compiler version installed.
opam switch system C system System compiler (4.00.1) -- -- 4.04.2 Official 4.04.2 release -- -- 4.05.0 Official 4.05.0 release -- -- 4.06.0 Official 4.06.0 release
If, as in this case, your system compiler is older than
4.06.0, you should install a more up to date version
of the compiler, as shown below.
opam switch 4.06.0 eval `opam config env`
switch itself will take around ten or fifteen
minutes on a modern machine, and will download and install the
OCaml compiler within the
~/.opam directory). You
can install multiple compilers at once, and switching between
them once they're installed is fast.
The new compiler and all libraries associated with it will be
Finally, we're ready to install the libraries and tools we'll
need for the book. The most important ones are
which provides the standard library that all the examples in the
book are based on, and
utop, which is the
interactive toplevel that you can use for working through the
opam install core utop
This will take about five or ten minutes to build, and will install the requested packages along with a bunch of dependencies. But there are other libraries that will be useful as you go through the book that you might as well install now.
opam install async yojson core_extended core_bench cohttp async_graphics cryptokit menhir
If some of the above don't work, don't worry too much. Most of
them come up in only a few places in the book. (There are some
known problems right now: in particular,
core_extended doesn't install cleanly on recent
versions of OS X, due to an issue with the
library it depends on. That is expected to be resolved soon.)
Note that if you've installed
utop and can't
launch it from the shell, make sure you've run
config env` in this shell. In general, you should just get
this set up as part of your shell init scripts, as described
Setting up and using
When you first run
utop, you'll find yourself at
an interactive prompt with a bar at the bottom of the screen. The
bottom bar dynamically updates as you write text, and contains
the possible names of modules or variables that are valid at that
point in the phrase you are entering. You can press the
<tab> key to complete the phrase with the
~/.ocamlinit file in your home directory
utop with common libraries and syntax
extensions so you don't need to type them in every time. Given
that you have Core installed, you should update your
ocamlinit to load Core every time you start
utop, by adding the following lines.
#use "topfind";; #thread;; #require "core.top";; #require "core.syntax";;
utop only you could get away with just the
last two lines, but you need the whole thing if you want the
ocaml toplevel to work too.
opam will have already added some lines
to the file. Also, notice that
# is used to mark a
toplevel directive, not a comment.
If you want to use Core as your primary standard library, then
you should open the
Core module by default,
which you can do by appending the following to the end of your
When you run
utop with these initialization
rules, it should start up with Core opened and ready to use. If
you don't open
Core by default, then you must
remember to open it before running any of the interactive
examples in the book.
These instructions have been tested on emacs 24.2 and should work for that version and newer. There are some reports of problems with earlier emacsen.
tuareg is the most commonly used mode for editing
OCaml code in emacs. You can download it here. You should download
it and untar it into some subdirectory of your home
Once you've done that, you can add the following rather
lengthy snippet to your
;; -- common-lisp compatibility if not added earlier in your .emacs (require 'cl) ;; -- Tuareg mode ----------------------------------------- ;; Add Tuareg to your search path (add-to-list 'load-path ;; Change the path below to be wherever you've put your tuareg installation. (expand-file-name "~/lib/elisp/tuareg")) (require 'tuareg) (setq auto-mode-alist (append '(("\\.ml[ily]?$" . tuareg-mode)) auto-mode-alist)) ;; -- Tweaks for OS X ------------------------------------- ;; Tweak for problem on OS X where Emacs.app doesn't run the right ;; init scripts when invoking a sub-shell (cond ((eq window-system 'ns) ; macosx ;; Invoke login shells, so that .profile or .bash_profile is read (setq shell-command-switch "-lc"))) ;; -- opam and utop setup -------------------------------- ;; Setup environment variables using opam (dolist (var (car (read-from-string (shell-command-to-string "opam config env --sexp")))) (setenv (car var) (cadr var))) ;; Update the emacs path (setq exec-path (split-string (getenv "PATH") path-separator)) ;; Update the emacs load path (push (concat (getenv "OCAML_TOPLEVEL_PATH") "/../../share/emacs/site-lisp") load-path) ;; Automatically load utop.el (autoload 'utop "utop" "Toplevel for OCaml" t) (autoload 'utop-setup-ocaml-buffer "utop" "Toplevel for OCaml" t) (add-hook 'tuareg-mode-hook 'utop-setup-ocaml-buffer)
Once this successfully loads in Emacs, you can run
utop by doing
M-x utop in Emacs. You
can also use commands like
Ctrl-c Ctrl-b to evaluate
your current buffer in
Ctrl-e to just evaluate a single expression.
There are more detailed instructions at the utop homepage.
Using Emacs24 packages
As an alternative to the setup above, here is a simplified OCaml setup using MELPA packages.
(require 'package) (add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/") t)
M-x package-install and install
Then add the rest of the configuration to
(add-hook 'tuareg-mode-hook 'tuareg-imenu-set-imenu) (setq auto-mode-alist (append '(("\\.ml[ily]?$" . tuareg-mode) ("\\.topml$" . tuareg-mode)) auto-mode-alist)) (autoload 'utop-setup-ocaml-buffer "utop" "Toplevel for OCaml" t) (add-hook 'tuareg-mode-hook 'utop-setup-ocaml-buffer) (add-hook 'tuareg-mode-hook 'merlin-mode) (setq merlin-use-auto-complete-mode t) (setq merlin-error-after-save nil)
Vim users can use the built-in style, and ocaml-annot may also be useful. For a more richly-featured setup, see the section on Merlin below.
Eclipse is a popular IDE usually used for Java development. The OCaml Development Tools (ODT) project provides equivalent IDE features for editing and compiling OCaml code, such as automatic compilation and name completion. Installation instructions can be found here
There are lots of other editors, and many of them come with built-in OCaml modes. These includes TextMate and Sublime Text for the Mac, and countless others.
There are a number of tools that are compatible with multiple
editors that can help you work more effectively with OCaml. Two
of the best are
which we'll describe below. Note that these are very much
optional. You might want to get started with the book before
getting back to setting these up.
Merlin provides a number of advanced IDE-like features, including:
- context-sensitive auto-completion
- interactive type-querying (i.e., you can ask it, "what is the type of this expression")
- error reporting -- it will highlight parts of your code that don't compile as you go.
You can install merlin with OPAM:
opam install merlin
Then you will need to add configuration for your editor. The following examples assume Merlin has been installed through OPAM as above.
A summary follows -- for more complete information, see Merlin's Emacs documentation.
;; -- merlin setup --------------------------------------- (setq opam-share (substring (shell-command-to-string "opam config var share") 0 -1)) (add-to-list 'load-path (concat opam-share "/emacs/site-lisp")) (require 'merlin) ;; Enable Merlin for ML buffers (add-hook 'tuareg-mode-hook 'merlin-mode) ;; So you can do it on a mac, where `C-<up>` and `C-<down>` are used ;; by spaces. (define-key merlin-mode-map (kbd "C-c <up>") 'merlin-type-enclosing-go-up) (define-key merlin-mode-map (kbd "C-c <down>") 'merlin-type-enclosing-go-down) (set-face-background 'merlin-type-face "#88FF44") ;; -- enable auto-complete ------------------------------- ;; Not required, but useful along with merlin-mode (require 'auto-complete) (add-hook 'tuareg-mode-hook 'auto-complete-mode)
Here are some of the more useful key commands that merlin provides:
merlin-type-enclosing: show you the type of the current expression.
C-<down>can then be used to look at the types of enclosing expressions, or drill down to smaller ones.
C-c <TAB>: if you have auto-complete set up, this gives you a list of possible auto-completions, along with their types. You can use
C-sto search within that list.
C-c C-l: to go to the definition of the value under your cursor.
C-c r: to restart merlin if it gets confused
A summary follows -- for more complete information, see
Merlin's Vim documentation and
" Your vimrc filetype plugin indent on syntax enable " Vim needs to be built with Python scripting support, and must be " able to find Merlin's executable on PATH. if executable('ocamlmerlin') && has('python') let s:ocamlmerlin = substitute(system('opam config var share'), '\n$', '', '''') . "/merlin" execute "set rtp+=".s:ocamlmerlin."/vim" execute "set rtp+=".s:ocamlmerlin."/vimbufsync" endif
As a one-time step after installation, index the documentation in Vim's help system:
:execute "helptags " . substitute(system('opam config var share'), '\n$', '', '''')
Some highlights of the functionality this enables:
- Autocompletion with Vim's omnicomplete system:
- Quick type checking with keybindings -- the defaults use
LocalLeader, which is normally backslash (
\) by default:
\t: type of expression under the cursor (also works with a visual selection).
\p: expand/contract the expression(s) to type check.
:Locate [identifier]: go to the definition of given identifier or the one under the cursor.
:Reload: if Merlin gets confused following build changes like new packages.
:GotoDotMerlin: edit the
.merlinproject configuration (see below).
The plugin can integrate with some other popular Vim plugins
such as Syntastic and neocomplcache -- see
merlin.txt for pointers.
Tell Merlin about your project layout
Regardless of which editor you use, you need to tell Merlin a
bit about the build environment you're working with in order for
it to work properly. This is done by creating a
.merlin file. If you're building applications based
on Core and Async using the
corebuild script (which
is built on top of
ocamlbuild), then the following
is a good starting point.
S . B _build PKG core PKG async PKG core_extended EXT nonrec
See the Merlin README for complete details of the file format.
ocp-indent is a source-code indenter which
includes a command-line tool, library and integration with emacs
and vi. It does a better job than most editor modes, including
tuareg, and has the advantage that it can be used as a
command-line tool and be integrated into multiple editors, so you
get consistent indentation across tools.
You can install it with
opam install ocp-indent
After installing through OPAM, simply load the file as follows to override tuareg-mode's indentation:
(setq opam-share (substring (shell-command-to-string "opam config var share") 0 -1)) (load-file (concat opam-share "/typerex/ocp-indent/ocp-indent.el"))
After installing through OPAM, simply add this
autocmd to your Vim configuration:
" Your vimrc autocmd FileType ocaml execute "set rtp+=" . substitute(system('opam config var share'), '\n$', '', '''') . "/ocp-indent/vim/indent/ocaml.vim"