The toplevel
If you are new to OCaml, the best place to start is probably the toplevel,
a minimal interactive environment in which you may write OCaml code and evaluate it
immediately, without having to go through a compilation process.
Launching the toplevel
To launch the toplevel from a terminal, open a terminal
and write
ocamlfind batteries/ocaml
If you have one of the tools rlwrap or ledit installed (either of
which is strongly suggested), open a terminal and, instead of the
previous command, write either
rlwrap ocamlfind batteries/ocaml
or
ledit ocamlfind batteries/ocaml
Finally, if you have Emacs and Tuareg, which is even more suggested,
instead of the previous commands, open Emacs, open a file whose
name ends with .ml
, press <Ctrl>-C-S
and, when Emacs asks you for the name of your OCaml toplevel, answer
ocamlfind batteries/ocaml
What is the toplevel?
You can think of the toplevel as a very powerful calculator or as a
command-line interface comparable to that of your operating system.
The role of this toplevel waits for your commands, evaluates them and
prints results. This makes it a nice way a to learn OCaml and to test
algorithms and data structures.
When you launch the toplevel, it displays something along the lines of:
Objective Caml version 3.10.2
__________________________________
| | | |
[| + | | Batteries Included - |
|_______|_|_______________________|
__________________________________
| | | |
[| + | | Type '#help;;' - |
|_______|_|_______________________|
Camlp4 Parsing version 3.10.2
#
The message informs you that you are running OCaml version 3.10.2,
with support for language extensions also in version 3.10.2 (this
support is called Camlp4) and that you are using the
complete OCaml platform (this platform is called OCaml,
Batteries Included) rather than a trimmed-down distribution
targetted for experiments or embedded systems.
See the #
at the end? This means that the toplevel
is waiting for an order. Whenever you see that character (except when
you've written it yourself, of course), it means that it's up
to you to write something.
Orders for the toplevel
Orders can take the form of value definitions, type definitions,
evaluations or directives. Value definitions let you teach OCaml new
tricks. Type definitions let you teach OCaml how to understand new
kinds of values informations and how to check that you're not making
mistakes when using your definitions. Evaluations let you actually do
something with your definitions, such as computing the result of your
algorithm, but also doing more complex things such as opening
applications, modifying files, or even creating websites. Any program
is composed of value definitions, type definitions and evaluations.
Finally, directives are not part of any program. They just let you
interact with the Toplevel, for instance by loading other programs,
reading the documentation, asking the Toplevel for information on
existing programs, etc. Directives are easy to spot, they also start
with character '#'.
Directives
The toplevel supports the following directives:
#quit;;
- This quits the toplevel immediately, without any error message.
#use "some_file.ml";;
- Load some source code from file
some_file.ml
.
Of course, this source code must be written in OCaml.
#require "some_package";;
- Load a library (actually, a package, which can contain several libraries).
Packages may add new functions, new type definitions, as well as new directives
or even modifications to the language.
#list;;
- List the packages installed on your system.
#browse "Some_module";;
- Inspect the contents of a module.
#help;;
- Ask for help.
#man "some subject";;
- Read the documentation on a given subject. This requires an installed Web browser.
#load "some_file.cmo";;
or #load "some_file.cma";;
- Load a module which has been previously compiled with OCaml.
By default, this module is searched in the current directory and in the directory containing OCaml's base library.
#directory "some directory/";;
- Instruct the toplevel to search for compiled modules in additional directories.
#trace some_function;;
(without quotes)- Instruct the toplevel to display useful debugging messages when running function
some_function
.
#untrace some_function;;
(without quotes)- Cancel a
#trace
.
A few additional low-level directives are available, which allow
customizing the manner in which OCaml should display values or errors.
Common error messages
Loading modules
Normally, none of these error messages can be displayed as the
consequence of loading a package with #require
, as this
command takes care of most of the underlying difficulties.
Cannot find filename.cmo or filename.cma
You have instructed OCaml to #load
some compiled module
but the toplevel cannot find it. You may have miswritten the name of
the file. More likely, this means that the file is in a directory
where OCaml doesn't know that it should be looking for it. To fix
this, use #directory
.
Cannot find filename.cmi
A file with suffix .cmi
contains information which tells OCaml how to use
a compiled module. If OCaml can find the corresponding .cmo
file but not
the .cmi
, it generally means that the file is missing, either because
compilation was not complete, because a program was improperly installed or sometimes
because the author of the module doesn't want people to use it.
Reference to undefined global Foo.
If you encounter this error message, it means that OCaml knows that
there should be a module called Foo
somewhere around,
because it is using code which requires that module, but the
the .cmo
or .cmi
for that module haven't
been loaded. To fix this, you need to #load
the
corresponding .cmo
/.cmi
.
Yes, this means that OCaml doesn't automatically attempt
to #load
modules it can't find. There is a simple reason
for this: you may have thousands of .cmo
installed on
your computer. Loading each of these modules could trigger programs,
which may run for long time and cause unwanted side-effects.
Consequently, the developers of OCaml decided that loading
of external modules would not be automatic. In other words,
you need to load them.
Writing code
This expression has type foo but is used with type bar
OCaml performs automatically rather advanced techniques for checking
that your code is correct and that it will execute without causing any
weird error. In fact, OCaml won't let you run code which would cause a
weird error.
This error message happens because OCaml has found an
inconsitency in your program: OCaml has determined that a part of your
code (the expression, which the toplevel has helpfully underlined for
you) will have a result of type foo
-- however, by examining
how the rest of your program uses that result, OCaml has also
determined that the rest of your program believes that the expression
should have type bar
, which is incoherent.
There is no magic bullet for this error. You need to find the error
in your program and fix it.
This expression has type foo but is used with type foo
This is a surprising error message: how can OCaml tell you that your
expression has type foo
but should have, well, the same
type foo
?
The explanation is actually quite simple: you have two types with
the same name. For some reason, usually as a consequence of copying
and pasting, you have defined a type foo
, then some
values of type foo
, and then a second type foo
and some other values of type foo
. The second type
foo
doesn't replace the first one, even if they may look
identical. Consequently, when you start attempting to mix values of
the first type foo
and values of the second
type foo
, OCaml deduces that there is something wrong.
Quite often, the solution to this problem is leaving the toplevel
and restarting it.