Fast and reliable programs with OCaml

Pattern Matching

OCaml's version of switch is match. Here, low numbers print as words, but anything else uses the built-in string_of_int function to display a decimal:

let to_string x =
  match x with
  | 1 -> "one"
  | 2 -> "two"
  | n -> string_of_int n

You can also match on strings, variants, records, and other complex values. OCaml will always check that you have covered every case. This is the key to its reliability.

Pattern matching can also be used in anonymous functions, like this:

let to_string = function
  | 1 -> "one"
  | 2 -> "two"
  | n -> string_of_int n

Anonymous functions are like lambda expressions in Python; you'll often see this shorter form.

Data Structures

OCaml allows you to define both variants (unions representing a choice of alternatives) and records (structs or named tuples holding several values at once). For example, the result of a download can be declared as a variant:

type download_result =
  | Success of filepath
  | Network_error of string
  | Aborted_by_user

This ensures that everywhere a URL downloads, it also handles a failed download (typically by displaying the error to the user) or a canceled download (not an error).

It's used as follows:

match download url with
| Success file -> process file
| Network_error msg -> alert msg
| Aborted_by_user -> ()

Notice that each case can only access the appropriate value: You can't accidentally try to use file if the download failed or display msg if it succeeded.

A record joins together several pieces of information:

type program = {
  name : string;
  homepage : url option;
}

Records and variants can be combined. In fact, the type url option in this record is itself a variant, because the homepage field can be either None or Some URL. By making optional types explicit, OCaml completely avoids Java's dreaded NullPointerException (or C's segfault).

OCaml also supports polymorphic (generic) types:

type 'a result =
  | Success of  'a
  | Error of exn

These allow you to construct whole families of types (e.g., int result, string result, or program result), while still writing generic code that can work on any of them, such as this function to return a result's value (or throw its exception):

let success = function
  | Success value -> value
  | Error ex -> raise ex

You don't have to declare variants before use; you can use the syntax `<tag> to let OCaml infer variant types automatically (examples below).

Loops

An unusual feature of functional programming is that loops are often written in a tail-recursive style (Listing 1). This prompts the user with a question, returning `yes if the user enters y or yes and so on.

Listing 1

Tail-Recursive Loops

 

If the user doesn't provide a valid response, it calls itself recursively to ask again. Because this recursive call is always the last thing the function does, OCaml does not need to store the return address on the stack, and you can loop any number of times without running out of memory. Effectively, the function call turns into a goto.

OCaml does support more traditional for and while loops, too, but the recursive form can be more elegant.

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