Fast and reliable programs with OCaml

Classes and Objects

Objects aren't often used by OCaml programmers, but they can be convenient, especially when porting existing code. The syntax is unusual, with a hash (#) rather than dot (.) indicating a method call.

Listing 3 shows a simple object-oriented GTK program. It also demonstrates the use of labeled function arguments (e.g., ~title). Unit is passed to mark the end of the optional arguments; otherwise, it's just a partially applied function.

Listing 3

GTK Dialog Box

 

OCaml's static type checking is particularly useful in GUI code, which is often hard to unit test. For example, if you remove any of the cases from the callback, the compiler will complain; it infers the set of possible responses from the calls to add_button and ensures they're all handled.

Mutability

OCaml encourages the use of immutable data structures. For example, lists are immutable, so you can share them with other parts of the program without worrying that they might be modified.

If you need mutability, you can use an array instead. Record fields are immutable by default but can be marked as mutable if necessary:

type stock_item = {
  id : stock_id;
  mutable location : position;
}

Here, the location of a stock item can change but not its ID.

The binding between names and values established using let is also immutable. If you need a value you can modify, you must create a mutable structure to hold it.

The following built-in syntax can help with this:

let total = ref 0 in
for i = 1 to 10 do
  total := !total + i
done;
Printf.printf
  "Total = %d\n" !total

Here, ref creates a new record containing a single mutable field (contents), !total gets the current value, and := modifies it.

Abstract Types

Suppose you have a module db.ml for querying a database of books. It might look similar to Listing 4. The search function takes a query string and returns a list of matching IDs and titles. These IDs can then be passed to functions such as author, but it would be easy to get confused by this API, perhaps passing an ID from a different table where a book ID is required.

Listing 4

Module to Query SQLite Database

 

To document a module and help ensure it is used correctly, OCaml lets you specify the module's interface using a .mli file. If you don't define one, OCaml will infer it automatically. To see the inferred version, use:

ocamlbuild -use-ocamlfind db.inferred.mli

In the _build directory, you'll find the inferred interface shown in Listing 5 (and yes, it inferred the types by looking inside the SQL queries). It's correct, but you can do better. You don't need to expose the Sqlexpr module or db, which are both implementation details. Also, because you're not using concurrency, you can drop Sqlexpr.result (if you had selected asynchronous mode, this would represent a promise for the result rather than the result itself). Finally, you should hide the fact that IDs are integers. Listing 6 shows the final version. You can save this as db.mli next to db.ml in the source directory, then just add type book_id = int to the db.ml file to complete it.

Listing 5

Inferred Module Interface

 

Listing 6

Cleaner Abstracted Interface

 

By abstracting away irrelevant details, such as the fact that you're using an SQL database and that IDs are integers, you make the API easier to understand and harder to misuse. This example also shows another handy OCaml feature: The SQL package adds a syntax extension for embedding SQL injection attack-free prepared statements as sqlc"".

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Batsh

    Batsh kills two birds with one stone: Programs written in this language can be compiled both as Linux Bash scripts and Windows batch files.

  • Helma

    The powerful Helma application server brings new powers to the JavaScript language. We'll show you how to use Helma to build a simple RSS reader.

  • File Comparison

    With support for more than 60 file formats, diffoscope extends the power of diff beyond the plain text or HTML file.

  • Highlight Learns F#

    The new version of Highlight, the software that highlights numerous program codes in color, supports amongst other languages, F#.

  • Let's Go!

    Released back in 2012, Go flew under the radar for a long time until showcase projects such as Docker pushed its popularity. Today, Go has become the language of choice of many system programmers.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More

News