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
(incl. VAT)
Buy Linux Magazine
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.
News
-
TUXEDO Computers Unveils Linux Laptop Featuring AMD Ryzen CPU
This latest release is the first laptop to include the new CPU from Ryzen and Linux preinstalled.
-
XZ Gets the All-Clear
The back door xz vulnerability has been officially reverted for Fedora 40 and versions 38 and 39 were never affected.
-
Canonical Collaborates with Qualcomm on New Venture
This new joint effort is geared toward bringing Ubuntu and Ubuntu Core to Qualcomm-powered devices.
-
Kodi 21.0 Open-Source Entertainment Hub Released
After a year of development, the award-winning Kodi cross-platform, media center software is now available with many new additions and improvements.
-
Linux Usage Increases in Two Key Areas
If market share is your thing, you'll be happy to know that Linux is on the rise in two areas that, if they keep climbing, could have serious meaning for Linux's future.
-
Vulnerability Discovered in xz Libraries
An urgent alert for Fedora 40 has been posted and users should pay attention.
-
Canonical Bumps LTS Support to 12 years
If you're worried that your Ubuntu LTS release won't be supported long enough to last, Canonical has a surprise for you in the form of 12 years of security coverage.
-
Fedora 40 Beta Released Soon
With the official release of Fedora 40 coming in April, it's almost time to download the beta and see what's new.
-
New Pentesting Distribution to Compete with Kali Linux
SnoopGod is now available for your testing needs
-
Juno Computers Launches Another Linux Laptop
If you're looking for a powerhouse laptop that runs Ubuntu, the Juno Computers Neptune 17 v6 should be on your radar.