OCaml Batteries Included

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