Tips for using the OCaml toplevel

Findlib

Use findlib to dynamically import modules from the toplevel. findlib is helpful from the command line, but it also makes it easy to require modules from the toplevel. For example:

   # #use "topfind";;
   - : unit = ()
   Findlib has been successfully loaded. Additional directives:
     #require "package";;      to load a package
     #list;;                   to list the available packages
     #camlp4o;;                to load camlp4 (standard syntax)
     #camlp4r;;                to load camlp4 (revised syntax)
     #predicates "p,q,...";;   to set these predicates
     Topfind.reset();;         to force that packages will be reloaded
     #thread;;                 to enable threads
   
   - : unit = ()
   # #require "num";;
   /usr/lib/ocaml/nums.cma: loaded
   /usr/lib/ocaml/site-packages/num-top: added to search path
   /usr/lib/ocaml/site-packages/num-top/num_top.cma: loaded
   /usr/lib/ocaml/site-packages/num: added to search path
   # Num.num_of_string "19283743237482";;
   - : Num.num = <num 19283743237482>

To ensure that #use "topfind" is always installed when OCaml's invoked, add that line to $HOME/.ocamlinit

This is a nice findlib tutorial with additional tips to get started.

Ledit

Ledit provides Emacs-style line editing behavior to the OCaml toplevel. Once installed, invoke ocaml using ledit:

   $ ledit ocaml

The toplevel should now support history and line-editing shortcuts. If you want to access commands from the previous sessions, the following options will do the job:

   $ ledit -x -h ~/.ocaml_history

To make this easier, add an alias using your shell's alias mechanism. For tcsh users, this involves adding a line to .cshrc:

   alias ocaml 'ledit -x -h ~/.ocaml_history'

and for bash resp. zsh users, adding a line into .bash_profile resp. .zshrc:

   alias ocaml='ledit -x -h ~/.ocaml_history'

rlwrap

rlwrap provides Readline-based line editing to the OCaml toplevel.

Input history is remembered across invocations, separately for each command; history completion and search work as in bash (using your bash settings, if any), and completion word lists can be specified on the command line.

Once installed, invoke ocaml using rlwrap:

   $ rlwrap ocaml

The toplevel should now support history and line-editing shortcuts. To make this easier, add an alias using your shell's alias mechanism. For tcsh users, this involves adding a line to .cshrc:

   alias ocaml "rlwrap ocaml"

and for bash resp. zsh users, adding a line into .bash_profile resp. .zshrc:

   alias ocaml="rlwrap ocaml"

Toplevel in Emacs with the Tuareg mode

The Tuareg mode for GNU Emacs or XEmacs provides an "evaluate phrase" and an "evaluate buffer" functionality which sends the OCaml code directly to an ocaml session inside of Emacs itself. This is faster than copy-pasting pieces of code from a text-editor to a terminal running ocaml. It provides naturally colored syntax, line editing and history (M-p, M-n).

Exploring libraries

Many OCaml libraries provide HTML documentation which is generated by ocamldoc. It uses comments written in a special format, which can be seen in the source files (.mli files usually). A way to explore those libraries is ocamlbrowser, a tool based on labltk, which is installed along with the labltk library. By default, only the libraries which are stored in the directory of the standard library are shown. Other libraries can be made visible by adding their directory to the search path interactively (Modules -> Path editor) or when launching ocamlbrowser from the command-line (-I option).

In the toplevel, there is currently no feature which allows to list all the different identifiers which are accessible. However, the signature of whole modules can be obtained by using this simple trick consisting of defining an alias for the module. This example will display the signature of the String module:

# module X = String;;
module X :
  sig
    external length : string -> int = "%string_length"
    external get : string -> int -> char = "%string_safe_get"
    external set : string -> int -> char -> unit = "%string_safe_set"
    external create : int -> string = "caml_create_string"
    val make : int -> char -> string
    val copy : string -> string
    val sub : string -> int -> int -> string
    val fill : string -> int -> int -> char -> unit
    val blit : string -> int -> string -> int -> int -> unit
...

It can be useful when you don't remember the exact name or arguments of a function (or type) provided by a given module from a library.

Testing modules of your own program

The OCaml toplevel offers two commands which allow you to "import" some code (that is besides the higher-level stuff provided by findlib/topfind - see above):

The #use directive may be convenient in certain cases for testing a single file. However it is much like a copy-paste, i.e. the definitions will not be wrapped into a module as it is the case when you compile a .ml file. If you are working under emacs with tuareg-mode, you probably won't use #use at all since you can send directly pieces of code from the source file to the toplevel.

Now, most programs contain several inter-dependent modules, and you may want to test these in the toplevel. #use won't work because if file b.ml calls a function f defined in a.ml, it will ask for A.f, not just f. So what you want to do is compile all of the modules of your program and load them, without preforming the main computations that would be done in the standalone program. For this you just have to compile your files to bytecode (using ocamlc -c). Then you have to load them one by one in the right order, which is a tedious task if done by hand. One solution to do all of that in one simple operation is to build a custom toplevel. OCamlMakefile provides a top target, i.e. make top will create a custom OCaml toplevel that loads all the modules of your program.

In order to not start the program when it's loaded in the toplevel, use this test:

if not !Sys.interactive then
  ... (* parse command-line arguments and do something *)