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
-
AlmaLinux Unveils New Hardware Certification Process
The AlmaLinux Hardware Certification Program run by the Certification Special Interest Group (SIG) aims to ensure seamless compatibility between AlmaLinux and a wide range of hardware configurations.
-
Wind River Introduces eLxr Pro Linux Solution
eLxr Pro offers an end-to-end Linux solution backed by expert commercial support.
-
Juno Tab 3 Launches with Ubuntu 24.04
Anyone looking for a full-blown Linux tablet need look no further. Juno has released the Tab 3.
-
New KDE Slimbook Plasma Available for Preorder
Powered by an AMD Ryzen CPU, the latest KDE Slimbook laptop is powerful enough for local AI tasks.
-
Rhino Linux Announces Latest "Quick Update"
If you prefer your Linux distribution to be of the rolling type, Rhino Linux delivers a beautiful and reliable experience.
-
Plasma Desktop Will Soon Ask for Donations
The next iteration of Plasma has reached the soft feature freeze for the 6.2 version and includes a feature that could be divisive.
-
Linux Market Share Hits New High
For the first time, the Linux market share has reached a new high for desktops, and the trend looks like it will continue.
-
LibreOffice 24.8 Delivers New Features
LibreOffice is often considered the de facto standard office suite for the Linux operating system.
-
Deepin 23 Offers Wayland Support and New AI Tool
Deepin has been considered one of the most beautiful desktop operating systems for a long time and the arrival of version 23 has bolstered that reputation.
-
CachyOS Adds Support for System76's COSMIC Desktop
The August 2024 release of CachyOS includes support for the COSMIC desktop as well as some important bits for video.