Previous Contents Next
Chapter 4 Labels and variants

(Chapter written by Jacques Garrigue)





This chapter gives an overview of the new features in Objective Caml 3: labels, and polymorphic variants.

4.1 Labels

If you have a look at modules ending in Labels in the standard library, you will see that function types have annotations you did not have in the functions you defined yourself.
#ListLabels.map;;
- : f:('a -> 'b) -> 'a list -> 'b list = <fun>
 
#StringLabels.sub;;
- : string -> pos:int -> len:int -> string = <fun>
Such annotations of the form name: are called labels. They are meant to document the code, allow more checking, and give more flexibility to function application. You can give such names to arguments in your programs, by prefixing them with a tilde ~.
#let f ~x ~y = x - y;;
val f : x:int -> y:int -> int = <fun>
 
#let x = 3 and y = 2 in f ~x ~y;;
- : int = 1
When you want to use distinct names for the variable and the label appearing in the type, you can use a naming label of the form ~name:. This also applies when the argument is not a variable.
#let f ~x:x1 ~y:y1 = x1 - y1;;
val f : x:int -> y:int -> int = <fun>
 
#f ~x:3 ~y:2;;
- : int = 1
Labels obey the same rules as other identifiers in Caml, that is you cannot use a reserved keyword (like in or to) as label.

Formal parameters and arguments are matched according to their respective labels1, the absence of label being interpreted as the empty label. This allows commuting arguments in applications. One can also partially apply a function on any argument, creating a new function of the remaining parameters.
#let f ~x ~y = x - y;;
val f : x:int -> y:int -> int = <fun>
 
#f ~y:2 ~x:3;;
- : int = 1
 
#ListLabels.fold_left;;
- : f:('a -> 'b -> 'a) -> init:'a -> 'b list -> 'a = <fun>
 
#ListLabels.fold_left [1;2;3] ~init:0 ~f:(+);;
- : int = 6
 
#ListLabels.fold_left ~init:0;;
- : f:(int -> 'a -> int) -> 'a list