Writing code with OCaml Batteries Included

In this chapter, we attempt to document best practices for writing code with OCaml Batteries Included. These best practices are bound to change with time, so don't hesitate to visit this page regularly and/or to submit rules.

Setting up your project

There are many ways of setting up a new project to use OCaml Batteries Included. A few possibilities are documented here. The easiest manner is generally to use OCamlBuild.

General guidelines

Be simple

OCaml is a multi-paradigm language. Out of the box, it features functional programming, imperative programming, object-oriented programming, concurrent programming and the often-overlooked stream programming. Extensions of OCaml add several distributed programming paradigms (JoCaml, Acute, BSML), safe dynamic programming (GCaml, coca-ml) or document processing (OCamlDuce). This makes the OCaml family an extremely powerful and versatile set of languages. This also gives many ways of writing confusing (and possibly unsafe) code by mixing a little bit too many styles. It is therefore generally a good idea to keep distinct paradigms local. In other words, don't hesitate to write object-oriented code but unless your whole project is object-oriented, try to keep object-orientation local to a module and, if you're writing a library, don't force your users to understand OCaml's take on object-oriented programming to use your library.

Data structures

No matter what type of algorithm you intend to implement, you will need data structures. While you will regularly need to implement your own data, OCaml Batteries Included provides numerous data structures, with which you should try to be familiar. Essentially, these data structures can be classified as either

Persistent
Lists, hash maps...
Mutable
Arrays, references, hash tables, doubly-linked lists...
Infinite
Streams, enumerations, inputs, outputs...

Numeric data structures

Input and output

Printing

Naming conventions

The usual naming conventions for OCaml apply.

Values

Values
The name of a value should be written entirely in lower-case. If the name consists in several words, these words should be separated by an underscore.
      (**This function computes a matrix*)
      val compute_matrix : unit -> 'a array array
    
Public functions which serve for conversion to/from another data structure should be called respectively to_name_of_the_other_data_structure and from_name_of_the_other_data_structure. An exception is conversion to enumerations, in which case the name of the function is simply enum.
Types
Constructors
Module names
Module types
Outer comments
Inner comments

Writing code for OCaml Batteries Included