IOCaml provides a browser based interface to the OCaml REPL with rich HTML based output. We call iocaml browser pages notebooks
and they are saved with a .ipynb
filename extension.
A notebook is made up of a vertically stacked set of cells
. Each cell can be code
, text
or a heading
.
Text cells are written in markdown
which is a simple text based format for describing bold or italic text, lists, tables etc. Markdown cells are edited in raw text format and displayed as html. Select then press <enter>
on a text cell (such as this one) to edit it, then press <shift>+<enter>
to display it. In addition, the markdown format supports arbitrary html
fragments along with a special math markup language called mathjax
.
Code cells are associated with a label In [x]:
along with a box to insert OCaml code. Press <shift>+<enter>
or <ctrl>+<enter>
to execute the cell. This will in turn create a code output cell with label Out [x]
and the compilers response along with any output generated by the code. For example,
In [ ]:
Printf.printf "Hello notebook" (* press ctrl+enter on this cell *)
Use the mouse or up and down arrow keys to move between cells. <shift>+<enter>
will execute
the current cell and move down to the next one (creating an empty code cell if needed). <ctrl>+<enter>
will execute
the current cell while remaining focussed on it.
Various other options for editing and manipulating the notebook exist in the menu bar and many can also be called with keyboard shortcuts prefixed with <ctrl>+m
. <ctrl>+m-h
will show a dialog box with all available keyboard shortcuts.
The IOCaml notebook interface can run on top of either a bytecode ocaml compiler (similar to the ocaml
or utop
commands) or a javascript based ocaml compiler.
When using the bytecode compiler a seperate ocaml process is spawned and interacted with over a network connection. In general it has much the same capabilities as a normal OCaml REPL including access to the file system, libraries etc.
When using the javascript option the compiler is embedded in the browser itself. This somewhat limits the capabilities of the compiler (access to the file system and libraries is still possible but has to be done via the IOCaml server). A notable limitation is the limited stack size javascript allows. On the other hand it gives complete access to the browser environment via js_of_ocaml
libraries.
In summary
The following will start IOCaml with the dashboard interface, which lists the notebooks found in the current directory. From the dashboard an existing or new notebook can be opened.
$ iocaml
An alternative directory can be specified with
$ iocaml /path/to/dir
or a notebook can be directly loaded, bypassing the dashboard, with
$ iocaml /path/notebook.ipynb
IOCaml supports the ocp-index library to enable tab completion of identifiers.
$ iocaml -completion -object-info ...
If .cmt[i]
files are installed, documentation is also available.
IOCaml is installed with two javascript kernels by default; min
and full
.
$ iocaml -js full ...
The min
kernel contains only the basic ocaml compiler. The full
kernel includes the js_of_ocaml
and lwt
libraries along with their camlp4 syntax extensions.
OCaml libraries can be accessed with -serve-jslibs
$ iocaml -js <kernel> -serve-jslibs ...
so long as the libraries are compatible with js_of_ocaml
(and do not blow the javascript stack!).
Additionally, IOCaml can serve parts of the host file system;
$ iocaml -js <kernel> -serve some/path ...
These are then accessed in the browser via calls such as open_in some/path/file
In [ ]:
#require "iocaml-kernel.notebook"
note; the #require is only required for byte code kernels
Iocaml.display is the easiest way to display rich content on the notebook. It takes two strings
For example
In [ ]:
Iocaml.display "text/html" "<b>hello <i style=\"color:red\">notebook</i><b>"
The html
data string can be generated with various ocaml libraries such as tyxml
or cow
to provide rich data representations.
The base64
optional argument will base64 encode the data string which is required for some mime types such as images. The context
argument can send output to other cells if needed (sometimes useful with multiple threads).