OCaml features you may not be familiar with
Here are some OCaml features that weren't discussed in CS 4, but which are very useful in day-to-day programming.
The |>
(pipe) operator
The |>
(pipe) operator is a reverse-apply operator
(analogous to a Unix pipe).
It's very convenient when you want to transform some inputs repeatedly
by applying one function after another.
Instead of writing this:
you can write this:
Aside from having fewer parentheses, it's often easier to read:
"Create data
, then apply func1
, func2
, and func3
to it in succession."
Also, because of OCaml's auto-currying of functions, it even works if one or more of the functions take additional arguments, just as long as the data structure is the last argument to the function. So we might have e.g.:
instead of:
Whether this is clearer is a matter of opinion.
When there are a lot of transformations, it's nice to write them on multiple lines:
This is much more readable than the usual notation:
and it's also easier to extend with more transformations.
The @@
(apply) operator
The "cousin" of the |>
operator is the @@
(forward apply) operator.
Like |>
, it's never required, but sometimes it can make code a bit nicer by
removing the need for some parentheses.
Note
If you know the Haskell language,
you'll recognize the @@
operator as the same thing
as the $
operator in Haskell.
The @@
operator is used to apply a function to its argument,
so f @@ x
is the same as f x
. Seems pointless, right?
But consider f (1 + 2)
. With @@
this becomes f @@ 1 + 2
and you've eliminated the need for the parentheses. Similarly:
can be written as:
and the parenthesis-saving is even greater! (Note that this operator associates to the right.)
A common use for this is when signalling errors. In the course compilers,
most errors use the failwith
function:
This is fine, but very often, the error message needs to contain formatted data e.g.
This can be rewritten using the @@
operator as:
and sometimes it's nice to put the Printf.sprintf
on its own line:
In fact, this case is so common
that we've written a helper function called failwithf
("failwith
with formatting").
Using that, we could rewrite the above code as:
Labelled arguments
OCaml has a neat feature called labelled arguments which we didn't cover in CS 4. Just like you'd expect, this feature means that you can label a function argument with a name, and you have to use that name when calling the function. What's nice is that you don't have to put labelled arguments in any particular order; as long as the label is there, the function will know what to do about them.
The syntax is described in detail in the link, but here's an example:
let f ~x ~y = x - y (* x and y are labelled arguments *)
let _ = f ~x:10 ~y:20 (* you need the labels when calling the function *)
let _ = f ~y:20 ~x:10 (* does the same thing *)
Why would you use this?
In our experience, the toughest OCaml bugs to track down are in functions that have more than one argument of the same type. It's easy to switch the arguments by mistake, and then you have a very hard-to-find bug.
The solution is to use labelled arguments. This way, when you call the function, you have to specify which argument you mean, which makes errors of this kind far less likely.
We're not suggesting you do this for every function, but it's certainly a trick to keep in mind, and one which we've used in much of the supporting code.
Also, OCaml supports optional arguments, which are like labelled arguments except the function gets a default value you specify if the labelled argument is left off. The link above describes those too.