~ubuntu-branches/ubuntu/hardy/ocaml-doc/hardy

« back to all changes in this revision

Viewing changes to ocaml.html/manual006.html

  • Committer: Bazaar Package Importer
  • Author(s): Samuel Mimram
  • Date: 2007-09-08 01:49:22 UTC
  • mfrom: (0.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20070908014922-lvihyehz0ndq7suu
Tags: 3.10-1
* New upstream release.
* Removed camlp4 documentation since it is not up-to-date.
* Updated to standards version 3.7.2, no changes needed.
* Updated my email address.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
<HTML>
4
4
<HEAD>
5
5
 
6
 
 
7
 
 
8
6
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
9
 
<META name="GENERATOR" content="hevea 1.08">
 
7
<META name="GENERATOR" content="hevea 1.09">
10
8
<LINK rel="stylesheet" type="text/css" href="manual.css">
11
 
<TITLE>
12
 
Labels and variants
13
 
</TITLE>
 
9
<TITLE>Labels and variants</TITLE>
14
10
</HEAD>
15
11
<BODY >
16
 
<A HREF="manual005.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
17
 
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
18
 
<A HREF="manual007.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
 
12
<A HREF="manual005.html"><IMG SRC="previous_motif.gif" ALT="Previous"></A>
 
13
<A HREF="index.html"><IMG SRC="contents_motif.gif" ALT="Up"></A>
 
14
<A HREF="manual007.html"><IMG SRC="next_motif.gif" ALT="Next"></A>
19
15
<HR>
20
 
 
21
 
<H1 CLASS="chapter"><A NAME="htoc36">Chapter&nbsp;4</A>&nbsp;&nbsp;Labels and variants</H1> <A NAME="c:labl-examples"></A>
22
 
 
23
 
<I>(Chapter written by Jacques Garrigue)</I><BR>
24
 
<BR>
25
 
<BR>
26
 
<BR>
27
 
<BR>
28
 
<BR>
29
 
This chapter gives an overview of the new features in
30
 
Objective Caml 3: labels, and polymorphic variants.<BR>
31
 
<BR>
32
 
 
33
 
<H2 CLASS="section"><A NAME="htoc37">4.1</A>&nbsp;&nbsp;Labels</H2>
34
 
 
35
 
If you have a look at modules ending in <TT>Labels</TT> in the standard
 
16
<H1 CLASS="chapter"><A NAME="htoc36">Chapter�4</A>��Labels and variants</H1><P> <A NAME="c:labl-examples"></A>
 
17
</P><P><I>(Chapter written by Jacques Garrigue)</I></P><P><BR>
 
18
<BR>
 
19
</P><P>This chapter gives an overview of the new features in
 
20
Objective Caml 3: labels, and polymorphic variants.</P><H2 CLASS="section"><A NAME="htoc37">4.1</A>��Labels</H2><P>If you have a look at modules ending in <TT>Labels</TT> in the standard
36
21
library, you will see that function types have annotations you did not
37
 
have in the functions you defined yourself.
38
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>ListLabels.map;;
 
22
have in the functions you defined yourself.</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>ListLabels.map;;
39
23
</FONT><FONT COLOR=maroon>- : f:('a -&gt; 'b) -&gt; 'a list -&gt; 'b list = &lt;fun&gt;
40
 
&nbsp;
 
24
41
25
<FONT COLOR=black>#</FONT><FONT COLOR=blue>StringLabels.sub;;
42
26
</FONT>- : string -&gt; pos:int -&gt; len:int -&gt; string = &lt;fun&gt;
43
 
</FONT></PRE>
44
 
Such annotations of the form <TT>name:</TT> are called <EM>labels</EM>. They are
 
27
</FONT></PRE><P>Such annotations of the form <TT>name:</TT> are called <EM>labels</EM>. They are
45
28
meant to document the code, allow more checking, and give more
46
29
flexibility to function application.
47
30
You can give such names to arguments in your programs, by prefixing them
48
 
with a tilde <TT>~</TT>.
49
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let f ~x ~y = x - y;;
 
31
with a tilde <TT>~</TT>.</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let f ~x ~y = x - y;;
50
32
</FONT><FONT COLOR=maroon>val f : x:int -&gt; y:int -&gt; int = &lt;fun&gt;
51
 
&nbsp;
 
33
52
34
<FONT COLOR=black>#</FONT><FONT COLOR=blue>let x = 3 and y = 2 in f ~x ~y;;
53
35
</FONT>- : int = 1
54
 
</FONT></PRE>
55
 
When you want to use distinct names for the variable and the label
 
36
</FONT></PRE><P>When you want to use distinct names for the variable and the label
56
37
appearing in the type, you can use a naming label of the form
57
 
<TT>~name:</TT>. This also applies when the argument is not a variable.
58
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let f ~x:x1 ~y:y1 = x1 - y1;;
 
38
<TT>~name:</TT>. This also applies when the argument is not a variable.</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let f ~x:x1 ~y:y1 = x1 - y1;;
59
39
</FONT><FONT COLOR=maroon>val f : x:int -&gt; y:int -&gt; int = &lt;fun&gt;
60
 
&nbsp;
 
40
61
41
<FONT COLOR=black>#</FONT><FONT COLOR=blue>f ~x:3 ~y:2;;
62
42
</FONT>- : int = 1
63
 
</FONT></PRE>
64
 
Labels obey the same rules as other identifiers in Caml, that is you
65
 
cannot use a reserved keyword (like <TT>in</TT> or <TT>to</TT>) as label.<BR>
66
 
<BR>
67
 
Formal parameters and arguments are matched according to their
 
43
</FONT></PRE><P>Labels obey the same rules as other identifiers in Caml, that is you
 
44
cannot use a reserved keyword (like <TT>in</TT> or <TT>to</TT>) as label.</P><P>Formal parameters and arguments are matched according to their
68
45
respective labels<SUP><A NAME="text1" HREF="#note1">1</A></SUP>, the absence of label
69
46
being interpreted as the empty label.
70
47
This allows commuting arguments in applications. One can also
71
48
partially apply a function on any argument, creating a new function of
72
 
the remaining parameters.
73
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let f ~x ~y = x - y;;
 
49
the remaining parameters.</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let f ~x ~y = x - y;;
74
50
</FONT><FONT COLOR=maroon>val f : x:int -&gt; y:int -&gt; int = &lt;fun&gt;
75
 
&nbsp;
 
51
76
52
<FONT COLOR=black>#</FONT><FONT COLOR=blue>f ~y:2 ~x:3;;
77
53
</FONT>- : int = 1
78
 
&nbsp;
 
54
79
55
<FONT COLOR=black>#</FONT><FONT COLOR=blue>ListLabels.fold_left;;
80
56
</FONT>- : f:('a -&gt; 'b -&gt; 'a) -&gt; init:'a -&gt; 'b list -&gt; 'a = &lt;fun&gt;
81
 
&nbsp;
 
57
82
58
<FONT COLOR=black>#</FONT><FONT COLOR=blue>ListLabels.fold_left [1;2;3] ~init:0 ~f:(+);;
83
59
</FONT>- : int = 6
84
 
&nbsp;
 
60
85
61
<FONT COLOR=black>#</FONT><FONT COLOR=blue>ListLabels.fold_left ~init:0;;
86
62
</FONT>- : f:(int -&gt; 'a -&gt; int) -&gt; 'a list -&gt; int = &lt;fun&gt;
87
 
</FONT></PRE>
88
 
If in a function several arguments bear the same label (or no label),
 
63
</FONT></PRE><P>If in a function several arguments bear the same label (or no label),
89
64
they will not commute among themselves, and order matters. But they
90
 
can still commute with other arguments.
91
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let hline ~x:x1 ~x:x2 ~y = (x1, x2, y);;
 
65
can still commute with other arguments.</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let hline ~x:x1 ~x:x2 ~y = (x1, x2, y);;
92
66
</FONT><FONT COLOR=maroon>val hline : x:'a -&gt; x:'b -&gt; y:'c -&gt; 'a * 'b * 'c = &lt;fun&gt;
93
 
&nbsp;
 
67
94
68
<FONT COLOR=black>#</FONT><FONT COLOR=blue>hline ~x:3 ~y:2 ~x:5;;
95
69
</FONT>- : int * int * int = (3, 5, 2)
96
 
</FONT></PRE>
97
 
As an exception to the above parameter matching rules, if an
 
70
</FONT></PRE><P>As an exception to the above parameter matching rules, if an
98
71
application is total, labels may be omitted. In practice, most
99
72
applications are total, so that labels can be omitted in applications.
100
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>f 3 2;;
 
73
</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>f 3 2;;
101
74
</FONT><FONT COLOR=maroon>- : int = 1
102
 
&nbsp;
 
75
103
76
<FONT COLOR=black>#</FONT><FONT COLOR=blue>ListLabels.map succ [1;2;3];;
104
77
</FONT>- : int list = [2; 3; 4]
105
 
</FONT></PRE>
 
78
</FONT></PRE><P>
106
79
But beware that functions like <TT>ListLabels.fold_left</TT> whose result
107
80
type is a type variable will never be considered as totally applied.
108
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>ListLabels.fold_left <U>(+)</U> 0 [1;2;3];;
 
81
</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>ListLabels.fold_left <U>(+)</U> 0 [1;2;3];;
109
82
</FONT><FONT COLOR=maroon>This expression has type int -&gt; int -&gt; int but is here used with type 'a list
110
 
</FONT></PRE>
111
 
When a function is passed as an argument to an higher-order function,
 
83
</FONT></PRE><P>When a function is passed as an argument to an higher-order function,
112
84
labels must match in both types. Neither adding nor removing labels
113
85
are allowed.
114
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let h g = g ~x:3 ~y:2;;
 
86
</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let h g = g ~x:3 ~y:2;;
115
87
</FONT><FONT COLOR=maroon>val h : (x:int -&gt; y:int -&gt; 'a) -&gt; 'a = &lt;fun&gt;
116
 
&nbsp;
 
88
117
89
<FONT COLOR=black>#</FONT><FONT COLOR=blue>h f;;
118
90
</FONT>- : int = 1
119
 
&nbsp;
 
91
120
92
<FONT COLOR=black>#</FONT><FONT COLOR=blue>h <U>(+)</U>;;
121
93
</FONT>This expression has type int -&gt; int -&gt; int but is here used with type
122
94
  x:int -&gt; y:int -&gt; 'a
123
 
</FONT></PRE>
124
 
 
125
 
<H3 CLASS="subsection"><A NAME="htoc38">4.1.1</A>&nbsp;&nbsp;Optional arguments</H3>
126
 
An interesting feature of labeled arguments is that they can be made
 
95
</FONT></PRE><P>
 
96
Note that when you don't need an argument, you can still use a wildcard
 
97
pattern, but you must prefix it with the label.
 
98
</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>h (fun ~x:_ ~y -&gt; y+1);;
 
99
</FONT><FONT COLOR=maroon>- : int = 3
 
100
</FONT></PRE><H3 CLASS="subsection"><A NAME="htoc38">4.1.1</A>��Optional arguments</H3><P>An interesting feature of labeled arguments is that they can be made
127
101
optional. For optional parameters, the question mark <TT>?</TT> replaces the
128
102
tilde <TT>~</TT> of non-optional ones, and the label is also prefixed by <TT>?</TT>
129
103
in the function type.
130
 
Default values may be given for such optional parameters.
131
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let bump ?(step = 1) x = x + step;;
 
104
Default values may be given for such optional parameters.</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let bump ?(step = 1) x = x + step;;
132
105
</FONT><FONT COLOR=maroon>val bump : ?step:int -&gt; int -&gt; int = &lt;fun&gt;
133
 
&nbsp;
 
106
134
107
<FONT COLOR=black>#</FONT><FONT COLOR=blue>bump 2;;
135
108
</FONT>- : int = 3
136
 
&nbsp;
 
109
137
110
<FONT COLOR=black>#</FONT><FONT COLOR=blue>bump ~step:3 2;;
138
111
</FONT>- : int = 5
139
 
</FONT></PRE>
140
 
A function taking some optional arguments must also take at least one
 
112
</FONT></PRE><P>A function taking some optional arguments must also take at least one
141
113
non-labeled argument. This is because the criterion for deciding
142
114
whether an optional has been omitted is the application on a
143
115
non-labeled argument appearing after this optional argument in the
144
 
function type.
145
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let test ?(x = 0) ?(y = 0) () ?(z = 0) () = (x, y, z);;
 
116
function type.</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let test ?(x = 0) ?(y = 0) () ?(z = 0) () = (x, y, z);;
146
117
</FONT><FONT COLOR=maroon>val test : ?x:int -&gt; ?y:int -&gt; unit -&gt; ?z:int -&gt; unit -&gt; int * int * int =
147
118
  &lt;fun&gt;
148
 
&nbsp;
 
119
149
120
<FONT COLOR=black>#</FONT><FONT COLOR=blue>test ();;
150
121
</FONT>- : ?z:int -&gt; unit -&gt; int * int * int = &lt;fun&gt;
151
 
&nbsp;
 
122
152
123
<FONT COLOR=black>#</FONT><FONT COLOR=blue>test ~x:2 () ~z:3 ();;
153
124
</FONT>- : int * int * int = (2, 0, 3)
154
 
</FONT></PRE>
155
 
Optional parameters may also commute with non-optional or unlabelled
 
125
</FONT></PRE><P>Optional parameters may also commute with non-optional or unlabelled
156
126
ones, as long as they are applied simultaneously. By nature, optional
157
127
arguments do not commute with unlabeled arguments applied
158
128
independently.
159
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>test ~y:2 ~x:3 () ();;
 
129
</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>test ~y:2 ~x:3 () ();;
160
130
</FONT><FONT COLOR=maroon>- : int * int * int = (3, 2, 0)
161
 
&nbsp;
 
131
162
132
<FONT COLOR=black>#</FONT><FONT COLOR=blue>test () () ~z:1 ~y:2 ~x:3;;
163
133
</FONT>- : int * int * int = (3, 2, 1)
164
 
&nbsp;
 
134
165
135
<FONT COLOR=black>#</FONT><FONT COLOR=blue><U>(test () ())</U> ~z:1;;
166
136
</FONT>This expression is not a function, it cannot be applied
167
 
</FONT></PRE>
 
137
</FONT></PRE><P>
168
138
Here <TT>(test () ())</TT> is already <TT>(0,0,0)</TT> and cannot be further
169
 
applied.<BR>
170
 
<BR>
171
 
Optional arguments are actually implemented as option types. If
 
139
applied.</P><P>Optional arguments are actually implemented as option types. If
172
140
you do not give a default value, you have access to their internal
173
141
representation, <TT>type 'a option = None | Some of 'a</TT>. You can then
174
 
provide different behaviors when an argument is present or not.
175
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let bump ?step x =
 
142
provide different behaviors when an argument is present or not.</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let bump ?step x =
176
143
   match step with
177
144
   | None -&gt; x * 2
178
145
   | Some y -&gt; x + y
179
146
 ;;
180
147
</FONT><FONT COLOR=maroon>val bump : ?step:int -&gt; int -&gt; int = &lt;fun&gt;
181
 
</FONT></PRE>
182
 
It may also be useful to relay an optional argument from a function
 
148
</FONT></PRE><P>It may also be useful to relay an optional argument from a function
183
149
call to another. This can be done by prefixing the applied argument
184
150
with <TT>?</TT>. This question mark disables the wrapping of optional
185
 
argument in an option type.
186
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let test2 ?x ?y () = test ?x ?y () ();;
 
151
argument in an option type.</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let test2 ?x ?y () = test ?x ?y () ();;
187
152
</FONT><FONT COLOR=maroon>val test2 : ?x:int -&gt; ?y:int -&gt; unit -&gt; int * int * int = &lt;fun&gt;
188
 
&nbsp;
 
153
189
154
<FONT COLOR=black>#</FONT><FONT COLOR=blue>test2 ?x:None;;
190
155
</FONT>- : ?y:int -&gt; unit -&gt; int * int * int = &lt;fun&gt;
191
 
</FONT></PRE>
192
 
 
193
 
<H3 CLASS="subsection"><A NAME="htoc39">4.1.2</A>&nbsp;&nbsp;Labels and type inference</H3>
194
 
<A NAME="ss:label-inference"></A>
195
 
While they provide an increased comfort for writing function
 
156
</FONT></PRE><H3 CLASS="subsection"><A NAME="htoc39">4.1.2</A>��Labels and type inference</H3><P>
 
157
<A NAME="ss:label-inference"></A></P><P>While they provide an increased comfort for writing function
196
158
applications, labels and optional arguments have the pitfall that they
197
 
cannot be inferred as completely as the rest of the language.<BR>
198
 
<BR>
199
 
You can see it in the following two examples.
200
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let h' g = g ~y:2 ~x:3;;
 
159
cannot be inferred as completely as the rest of the language.</P><P>You can see it in the following two examples.
 
160
</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let h' g = g ~y:2 ~x:3;;
201
161
</FONT><FONT COLOR=maroon>val h' : (y:int -&gt; x:int -&gt; 'a) -&gt; 'a = &lt;fun&gt;
202
 
&nbsp;
 
162
203
163
<FONT COLOR=black>#</FONT><FONT COLOR=blue>h' <U>f</U>;;
204
164
</FONT>This expression has type x:int -&gt; y:int -&gt; int but is here used with type
205
165
  y:int -&gt; x:int -&gt; 'a
206
 
&nbsp;
 
166
207
167
<FONT COLOR=black>#</FONT><FONT COLOR=blue>let bump_it bump x =
208
168
   bump ~step:2 x;;
209
169
</FONT>val bump_it : (step:int -&gt; 'a -&gt; 'b) -&gt; 'a -&gt; 'b = &lt;fun&gt;
210
 
&nbsp;
 
170
211
171
<FONT COLOR=black>#</FONT><FONT COLOR=blue>bump_it <U>bump</U> 1;;
212
172
</FONT>This expression has type ?step:int -&gt; int -&gt; int but is here used with type
213
173
  step:int -&gt; 'a -&gt; 'b
214
 
</FONT></PRE>
 
174
</FONT></PRE><P>
215
175
The first case is simple: <TT>g</TT> is passed <TT>~y</TT> and then <TT>~x</TT>, but <TT>f</TT>
216
176
expects <TT>~x</TT> and then <TT>~y</TT>. This is correctly handled if we know the
217
177
type of <TT>g</TT> to be <TT>x:int -&gt; y:int -&gt; int</TT> in advance, but otherwise
218
178
this causes the above type clash. The simplest workaround is to apply
219
 
formal parameters in a standard order.<BR>
220
 
<BR>
221
 
The second example is more subtle: while we intended the argument
 
179
formal parameters in a standard order.</P><P>The second example is more subtle: while we intended the argument
222
180
<TT>bump</TT> to be of type <TT>?step:int -&gt; int -&gt; int</TT>, it is inferred as
223
181
<TT>step:int -&gt; int -&gt; 'a</TT>.
224
182
These two types being incompatible (internally normal and optional
225
183
arguments are different), a type error occurs when applying <TT>bump_it</TT>
226
 
to the real <TT>bump</TT>.<BR>
227
 
<BR>
228
 
We will not try here to explain in detail how type inference works.
 
184
to the real <TT>bump</TT>.</P><P>We will not try here to explain in detail how type inference works.
229
185
One must just understand that there is not enough information in the
230
186
above program to deduce the correct type of <TT>g</TT> or <TT>bump</TT>. That is,
231
187
there is no way to know whether an argument is optional or not, or
232
188
which is the correct order, by looking only at how a function is
233
189
applied. The strategy used by the compiler is to assume that there are
234
190
no optional arguments, and that applications are done in the right
235
 
order.<BR>
236
 
<BR>
237
 
The right way to solve this problem for optional parameters is to add
 
191
order.</P><P>The right way to solve this problem for optional parameters is to add
238
192
a type annotation to the argument <TT>bump</TT>.
239
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let bump_it (bump : ?step:int -&gt; int -&gt; int) x =
 
193
</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let bump_it (bump : ?step:int -&gt; int -&gt; int) x =
240
194
   bump ~step:2 x;;
241
195
</FONT><FONT COLOR=maroon>val bump_it : (?step:int -&gt; int -&gt; int) -&gt; int -&gt; int = &lt;fun&gt;
242
 
&nbsp;
 
196
243
197
<FONT COLOR=black>#</FONT><FONT COLOR=blue>bump_it bump 1;;
244
198
</FONT>- : int = 3
245
 
</FONT></PRE>
 
199
</FONT></PRE><P>
246
200
In practive, such problems appear mostly when using objects whose
247
201
methods have optional arguments, so that writing the type of object
248
 
arguments is often a good idea.<BR>
249
 
<BR>
250
 
Normally the compiler generates a type error if you attempt to pass to
 
202
arguments is often a good idea.</P><P>Normally the compiler generates a type error if you attempt to pass to
251
203
a function a parameter whose type is different from the expected one.
252
204
However, in the specific case where the expected type is a non-labeled
253
205
function type, and the argument is a function expecting optional
254
206
parameters, the compiler will attempt to transform the argument to
255
207
have it match the expected type, by passing <TT>None</TT> for all optional
256
 
parameters.
257
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let twice f (x : int) = f(f x);;
 
208
parameters.</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let twice f (x : int) = f(f x);;
258
209
</FONT><FONT COLOR=maroon>val twice : (int -&gt; int) -&gt; int -&gt; int = &lt;fun&gt;
259
 
&nbsp;
 
210
260
211
<FONT COLOR=black>#</FONT><FONT COLOR=blue>twice bump 2;;
261
212
</FONT>- : int = 8
262
 
</FONT></PRE>
263
 
This transformation is coherent with the intended semantics,
 
213
</FONT></PRE><P>This transformation is coherent with the intended semantics,
264
214
including side-effects. That is, if the application of optional
265
215
parameters shall produce side-effects, these are delayed until the
266
 
received function is really applied to an argument.<BR>
267
 
<BR>
268
 
 
269
 
<H3 CLASS="subsection"><A NAME="htoc40">4.1.3</A>&nbsp;&nbsp;Suggestions for labeling</H3>
270
 
Like for names, choosing labels for functions is not an easy task. A
271
 
good labeling is a labeling which
272
 
<UL CLASS="itemize"><LI CLASS="li-itemize">
 
216
received function is really applied to an argument.</P><H3 CLASS="subsection"><A NAME="htoc40">4.1.3</A>��Suggestions for labeling</H3><P>Like for names, choosing labels for functions is not an easy task. A
 
217
good labeling is a labeling which</P><UL CLASS="itemize"><LI CLASS="li-itemize">
273
218
makes programs more readable,
274
 
<LI CLASS="li-itemize">is easy to remember,
275
 
<LI CLASS="li-itemize">when possible, allows useful partial applications.
276
 
</UL>
277
 
We explain here the rules we applied when labeling Objective Caml
278
 
libraries.<BR>
279
 
<BR>
280
 
To speak in an &#8220;object-oriented&#8221; way, one can consider that each
 
219
</LI><LI CLASS="li-itemize">is easy to remember,
 
220
</LI><LI CLASS="li-itemize">when possible, allows useful partial applications.
 
221
</LI></UL><P>We explain here the rules we applied when labeling Objective Caml
 
222
libraries.</P><P>To speak in an &#X201C;object-oriented&#X201D; way, one can consider that each
281
223
function has a main argument, its <EM>object</EM>, and other arguments
282
224
related with its action, the <EM>parameters</EM>. To permit the
283
225
combination of functions through functionals in commuting label mode, the
287
229
role. When this is not possible the role is to prefer, since the nature will
288
230
often be given by the type itself. Obscure abbreviations should be
289
231
avoided.
290
 
<PRE><FONT COLOR=maroon>ListLabels.map : f:('a -&gt; 'b) -&gt; 'a list -&gt; 'b list
 
232
</P><PRE><FONT COLOR=maroon>ListLabels.map : f:('a -&gt; 'b) -&gt; 'a list -&gt; 'b list
291
233
UnixLabels.write : file_descr -&gt; buf:string -&gt; pos:int -&gt; len:int -&gt; unit
292
 
</FONT></PRE>
293
 
When there are several objects of same nature and role, they are all
 
234
</FONT></PRE><P>When there are several objects of same nature and role, they are all
294
235
left unlabeled.
295
 
<PRE><FONT COLOR=maroon>ListLabels.iter2 : f:('a -&gt; 'b -&gt; 'c) -&gt; 'a list -&gt; 'b list -&gt; unit
296
 
</FONT></PRE>
297
 
When there is no preferable object, all arguments are labeled.
298
 
<PRE><FONT COLOR=maroon>StringLabels.blit :
 
236
</P><PRE><FONT COLOR=maroon>ListLabels.iter2 : f:('a -&gt; 'b -&gt; 'c) -&gt; 'a list -&gt; 'b list -&gt; unit
 
237
</FONT></PRE><P>When there is no preferable object, all arguments are labeled.
 
238
</P><PRE><FONT COLOR=maroon>StringLabels.blit :
299
239
  src:string -&gt; src_pos:int -&gt; dst:string -&gt; dst_pos:int -&gt; len:int -&gt; unit
300
 
</FONT></PRE>
301
 
However, when there is only one argument, it is often left unlabeled.
302
 
<PRE><FONT COLOR=maroon>StringLabels.create : int -&gt; string
303
 
</FONT></PRE>
 
240
</FONT></PRE><P>However, when there is only one argument, it is often left unlabeled.
 
241
</P><PRE><FONT COLOR=maroon>StringLabels.create : int -&gt; string
 
242
</FONT></PRE><P>
304
243
This principle also applies to functions of several arguments whose
305
244
return type is a type variable, as long as the role of each argument
306
245
is not ambiguous. Labeling such functions may lead to awkward error
307
246
messages when one attempts to omit labels in an application, as we
308
 
have seen with <TT>ListLabels.fold_left</TT>.<BR>
309
 
<BR>
310
 
Here are some of the label names you will find throughout the
311
 
libraries.<BR>
312
 
<BR>
313
 
<DIV CLASS="center"><TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1 WIDTH="80%">
314
 
<TR><TD ALIGN=center NOWRAP><B>Label</B></TD>
315
 
<TD ALIGN=center NOWRAP><B>Meaning</B></TD>
316
 
</TR>
 
247
have seen with <TT>ListLabels.fold_left</TT>.</P><P>Here are some of the label names you will find throughout the
 
248
libraries.</P><DIV CLASS="center"><TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1 WIDTH="80%"><TR><TD ALIGN=center NOWRAP><B>Label</B></TD><TD ALIGN=center NOWRAP><B>Meaning</B></TD></TR>
317
249
<TR><TD ALIGN=left NOWRAP>
318
 
<TT>f:</TT></TD>
319
 
<TD ALIGN=left NOWRAP>a function to be applied</TD>
320
 
</TR>
321
 
<TR><TD ALIGN=left NOWRAP><TT>pos:</TT></TD>
322
 
<TD ALIGN=left NOWRAP>a position in a string or array</TD>
323
 
</TR>
324
 
<TR><TD ALIGN=left NOWRAP><TT>len:</TT></TD>
325
 
<TD ALIGN=left NOWRAP>a length</TD>
326
 
</TR>
327
 
<TR><TD ALIGN=left NOWRAP><TT>buf:</TT></TD>
328
 
<TD ALIGN=left NOWRAP>a string used as buffer</TD>
329
 
</TR>
330
 
<TR><TD ALIGN=left NOWRAP><TT>src:</TT></TD>
331
 
<TD ALIGN=left NOWRAP>the source of an operation</TD>
332
 
</TR>
333
 
<TR><TD ALIGN=left NOWRAP><TT>dst:</TT></TD>
334
 
<TD ALIGN=left NOWRAP>the destination of an operation</TD>
335
 
</TR>
336
 
<TR><TD ALIGN=left NOWRAP><TT>init:</TT></TD>
337
 
<TD ALIGN=left NOWRAP>the initial value for an iterator</TD>
338
 
</TR>
339
 
<TR><TD ALIGN=left NOWRAP><TT>cmp:</TT></TD>
340
 
<TD ALIGN=left NOWRAP>a comparison function, <I>e.g.</I> <TT>Pervasives.compare</TT></TD>
341
 
</TR>
342
 
<TR><TD ALIGN=left NOWRAP><TT>mode:</TT></TD>
343
 
<TD ALIGN=left NOWRAP>an operation mode or a flag list</TD>
344
 
</TR></TABLE></DIV><BR>
345
 
<BR>
346
 
All these are only suggestions, but one shall keep in mind that the
 
250
<TT>f:</TT></TD><TD ALIGN=left NOWRAP>a function to be applied</TD></TR>
 
251
<TR><TD ALIGN=left NOWRAP><TT>pos:</TT></TD><TD ALIGN=left NOWRAP>a position in a string or array</TD></TR>
 
252
<TR><TD ALIGN=left NOWRAP><TT>len:</TT></TD><TD ALIGN=left NOWRAP>a length</TD></TR>
 
253
<TR><TD ALIGN=left NOWRAP><TT>buf:</TT></TD><TD ALIGN=left NOWRAP>a string used as buffer</TD></TR>
 
254
<TR><TD ALIGN=left NOWRAP><TT>src:</TT></TD><TD ALIGN=left NOWRAP>the source of an operation</TD></TR>
 
255
<TR><TD ALIGN=left NOWRAP><TT>dst:</TT></TD><TD ALIGN=left NOWRAP>the destination of an operation</TD></TR>
 
256
<TR><TD ALIGN=left NOWRAP><TT>init:</TT></TD><TD ALIGN=left NOWRAP>the initial value for an iterator</TD></TR>
 
257
<TR><TD ALIGN=left NOWRAP><TT>cmp:</TT></TD><TD ALIGN=left NOWRAP>a comparison function, <I>e.g.</I> <TT>Pervasives.compare</TT></TD></TR>
 
258
<TR><TD ALIGN=left NOWRAP><TT>mode:</TT></TD><TD ALIGN=left NOWRAP>an operation mode or a flag list</TD></TR>
 
259
</TABLE></DIV><P>All these are only suggestions, but one shall keep in mind that the
347
260
choice of labels is essential for readability. Bizarre choices will
348
 
make the program harder to maintain.<BR>
349
 
<BR>
350
 
In the ideal, the right function name with right labels shall be
 
261
make the program harder to maintain.</P><P>In the ideal, the right function name with right labels shall be
351
262
enough to understand the function's meaning. Since one can get this
352
263
information with OCamlBrowser or the <TT>ocaml</TT> toplevel, the documentation
353
 
is only used when a more detailed specification is needed.<BR>
354
 
<BR>
355
 
 
356
 
<H2 CLASS="section"><A NAME="htoc41">4.2</A>&nbsp;&nbsp;Polymorphic variants</H2>
357
 
 
358
 
Variants as presented in section&nbsp;<A HREF="manual003.html#s:tut-recvariants">1.4</A> are a
 
264
is only used when a more detailed specification is needed.</P><H2 CLASS="section"><A NAME="htoc41">4.2</A>��Polymorphic variants</H2><P>Variants as presented in section�<A HREF="manual003.html#s:tut-recvariants">1.4</A> are a
359
265
powerful tool to build data structures and algorithms. However they
360
266
sometimes lack flexibility when used in modular programming. This is
361
267
due to the fact every constructor reserves a name to be used with a
362
268
unique type. One cannot use the same name in another type, or consider
363
269
a value of some type to belong to some other type with more
364
 
constructors.<BR>
365
 
<BR>
366
 
With polymorphic variants, this original assumption is removed. That
 
270
constructors.</P><P>With polymorphic variants, this original assumption is removed. That
367
271
is, a variant tag does not belong to any type in particular, the type
368
272
system will just check that it is an admissible value according to its
369
273
use. You need not define a type before using a variant tag. A variant
370
 
type will be inferred independently for each of its uses.<BR>
371
 
<BR>
372
 
 
373
 
<H3 CLASS="subsection">Basic use</H3>
374
 
In programs, polymorphic variants work like usual ones. You just have
 
274
type will be inferred independently for each of its uses.</P><H3 CLASS="subsection">Basic use</H3><P>In programs, polymorphic variants work like usual ones. You just have
375
275
to prefix their names with a backquote character <TT>`</TT>.
376
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>[`On; `Off];;
 
276
</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>[`On; `Off];;
377
277
</FONT><FONT COLOR=maroon>- : [&gt; `Off | `On ] list = [`On; `Off]
378
 
&nbsp;
 
278
379
279
<FONT COLOR=black>#</FONT><FONT COLOR=blue>`Number 1;;
380
280
</FONT>- : [&gt; `Number of int ] = `Number 1
381
 
&nbsp;
 
281
382
282
<FONT COLOR=black>#</FONT><FONT COLOR=blue>let f = function `On -&gt; 1 | `Off -&gt; 0 | `Number n -&gt; n;;
383
283
</FONT>val f : [&lt; `Number of int | `Off | `On ] -&gt; int = &lt;fun&gt;
384
 
&nbsp;
 
284
385
285
<FONT COLOR=black>#</FONT><FONT COLOR=blue>List.map f [`On; `Off];;
386
286
</FONT>- : int list = [1; 0]
387
 
</FONT></PRE>
 
287
</FONT></PRE><P>
388
288
<TT>[&gt;`Off|`On] list</TT> means that to match this list, you should at
389
289
least be able to match <TT>`Off</TT> and <TT>`On</TT>, without argument.
390
290
<TT>[&lt;`On|`Off|`Number of int]</TT> means that <TT>f</TT> may be applied to <TT>`Off</TT>,
394
294
refined, either by defining more tags or allowing less. As such they
395
295
contain an implicit type variable. Both variant types appearing only
396
296
once in the type, the implicit type variables they constrain are not
397
 
shown.<BR>
398
 
<BR>
399
 
The above variant types were polymorphic, allowing further refinement.
 
297
shown.</P><P>The above variant types were polymorphic, allowing further refinement.
400
298
When writing type annotations, one will most often describe fixed
401
299
variant types, that is types that can be no longer refined. This is
402
300
also the case for type abbreviations. Such types do not contain <TT>&lt;</TT> or
403
301
<TT>&gt;</TT>, but just an enumeration of the tags and their associated types,
404
302
just like in a normal datatype definition. 
405
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>type 'a vlist = [`Nil | `Cons of 'a * 'a vlist];;
 
303
</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>type 'a vlist = [`Nil | `Cons of 'a * 'a vlist];;
406
304
</FONT><FONT COLOR=maroon>type 'a vlist = [ `Cons of 'a * 'a vlist | `Nil ]
407
 
&nbsp;
 
305
408
306
<FONT COLOR=black>#</FONT><FONT COLOR=blue>let rec map f : 'a vlist -&gt; 'b vlist = function
409
307
   | `Nil -&gt; `Nil
410
308
   | `Cons(a, l) -&gt; `Cons(f a, map f l)
411
309
 ;;
412
310
</FONT>val map : ('a -&gt; 'b) -&gt; 'a vlist -&gt; 'b vlist = &lt;fun&gt;
413
 
</FONT></PRE>
414
 
 
415
 
<H3 CLASS="subsection">Advanced use</H3>
416
 
Type-checking polymorphic variants is a subtle thing, and some
417
 
expressions may result in more complex type information.
418
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let f = function `A -&gt; `C | `B -&gt; `D | x -&gt; x;;
 
311
</FONT></PRE><H3 CLASS="subsection">Advanced use</H3><P>Type-checking polymorphic variants is a subtle thing, and some
 
312
expressions may result in more complex type information.</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let f = function `A -&gt; `C | `B -&gt; `D | x -&gt; x;;
419
313
</FONT><FONT COLOR=maroon>val f : ([&gt; `A | `B | `C | `D ] as 'a) -&gt; 'a = &lt;fun&gt;
420
 
&nbsp;
 
314
421
315
<FONT COLOR=black>#</FONT><FONT COLOR=blue>f `E;;
422
316
</FONT>- : [&gt; `A | `B | `C | `D | `E ] = `E
423
 
</FONT></PRE>
 
317
</FONT></PRE><P>
424
318
Here we are seeing two phenomena. First, since this matching is open
425
319
(the last case catches any tag), we obtain the type <TT>[&gt; `A | `B]</TT>
426
320
rather than <TT>[&lt; `A | `B]</TT> in a closed matching. Then, since <TT>x</TT> is
427
321
returned as is, input and return types are identical. The notation <TT>as 'a</TT> denotes such type sharing. If we apply <TT>f</TT> to yet another tag
428
 
<TT>`E</TT>, it gets added to the list.
429
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let f1 = function `A x -&gt; x = 1 | `B -&gt; true | `C -&gt; false
 
322
<TT>`E</TT>, it gets added to the list.</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let f1 = function `A x -&gt; x = 1 | `B -&gt; true | `C -&gt; false
430
323
 let f2 = function `A x -&gt; x = "a" | `B -&gt; true ;;
431
324
</FONT><FONT COLOR=maroon>val f1 : [&lt; `A of int | `B | `C ] -&gt; bool = &lt;fun&gt;
432
325
val f2 : [&lt; `A of string | `B ] -&gt; bool = &lt;fun&gt;
433
 
&nbsp;
 
326
434
327
<FONT COLOR=black>#</FONT><FONT COLOR=blue>let f x = f1 x &amp;&amp; f2 x;;
435
328
</FONT>val f : [&lt; `A of string &amp; int | `B ] -&gt; bool = &lt;fun&gt;
436
 
</FONT></PRE>
 
329
</FONT></PRE><P>
437
330
Here <TT>f1</TT> and <TT>f2</TT> both accept the variant tags <TT>`A</TT> and <TT>`B</TT>, but the
438
331
argument of <TT>`A</TT> is <TT>int</TT> for <TT>f1</TT> and <TT>string</TT> for <TT>f2</TT>. In <TT>f</TT>'s
439
332
type <TT>`C</TT>, only accepted by <TT>f1</TT>, disappears, but both argument types
440
333
appear for <TT>`A</TT> as <TT>int &amp; string</TT>. This means that if we
441
334
pass the variant tag <TT>`A</TT> to <TT>f</TT>, its argument should be <EM>both</EM>
442
335
<TT>int</TT> and <TT>string</TT>. Since there is no such value, <TT>f</TT> cannot be
443
 
applied to <TT>`A</TT>, and <TT>`B</TT> is the only accepted input.<BR>
444
 
<BR>
445
 
Even if a value has a fixed variant type, one can still give it a
 
336
applied to <TT>`A</TT>, and <TT>`B</TT> is the only accepted input.</P><P>Even if a value has a fixed variant type, one can still give it a
446
337
larger type through coercions. Coercions are normally written with
447
338
both the source type and the destination type, but in simple cases the
448
339
source type may be omitted.
449
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>type 'a wlist = [`Nil | `Cons of 'a * 'a wlist | `Snoc of 'a wlist * 'a];;
 
340
</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>type 'a wlist = [`Nil | `Cons of 'a * 'a wlist | `Snoc of 'a wlist * 'a];;
450
341
</FONT><FONT COLOR=maroon>type 'a wlist = [ `Cons of 'a * 'a wlist | `Nil | `Snoc of 'a wlist * 'a ]
451
 
&nbsp;
 
342
452
343
<FONT COLOR=black>#</FONT><FONT COLOR=blue>let wlist_of_vlist  l = (l : 'a vlist :&gt; 'a wlist);;
453
344
</FONT>val wlist_of_vlist : 'a vlist -&gt; 'a wlist = &lt;fun&gt;
454
 
&nbsp;
 
345
455
346
<FONT COLOR=black>#</FONT><FONT COLOR=blue>let open_vlist l = (l : 'a vlist :&gt; [&gt; 'a vlist]);;
456
347
</FONT>val open_vlist : 'a vlist -&gt; [&gt; 'a vlist ] = &lt;fun&gt;
457
 
&nbsp;
 
348
458
349
<FONT COLOR=black>#</FONT><FONT COLOR=blue>fun x -&gt; (x :&gt; [`A|`B|`C]);;
459
350
</FONT>- : [&lt; `A | `B | `C ] -&gt; [ `A | `B | `C ] = &lt;fun&gt;
460
 
</FONT></PRE>
461
 
You may also selectively coerce values through pattern matching.
462
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let split_cases = function
 
351
</FONT></PRE><P>You may also selectively coerce values through pattern matching.
 
352
</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let split_cases = function
463
353
   | `Nil | `Cons _ as x -&gt; `A x
464
354
   | `Snoc _ as x -&gt; `B x
465
355
 ;;
466
356
</FONT><FONT COLOR=maroon>val split_cases :
467
357
  [&lt; `Cons of 'a | `Nil | `Snoc of 'b ] -&gt;
468
358
  [&gt; `A of [&gt; `Cons of 'a | `Nil ] | `B of [&gt; `Snoc of 'b ] ] = &lt;fun&gt;
469
 
</FONT></PRE>
 
359
</FONT></PRE><P>
470
360
When an or-pattern composed of variant tags is wrapped inside an
471
361
alias-pattern, the alias is given a type containing only the tags
472
362
enumerated in the or-pattern. This allows for many useful idioms, like
473
 
incremental definition of functions.
474
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let num x = `Num x
 
363
incremental definition of functions.</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let num x = `Num x
475
364
 let eval1 eval (`Num x) = x
476
365
 let rec eval x = eval1 eval x ;;
477
366
</FONT><FONT COLOR=maroon>val num : 'a -&gt; [&gt; `Num of 'a ] = &lt;fun&gt;
478
367
val eval1 : 'a -&gt; [&lt; `Num of 'b ] -&gt; 'b = &lt;fun&gt;
479
368
val eval : [&lt; `Num of 'a ] -&gt; 'a = &lt;fun&gt;
480
 
&nbsp;
 
369
481
370
<FONT COLOR=black>#</FONT><FONT COLOR=blue>let plus x y = `Plus(x,y)
482
371
 let eval2 eval = function
483
372
   | `Plus(x,y) -&gt; eval x + eval y
486
375
</FONT>val plus : 'a -&gt; 'b -&gt; [&gt; `Plus of 'a * 'b ] = &lt;fun&gt;
487
376
val eval2 : ('a -&gt; int) -&gt; [&lt; `Num of int | `Plus of 'a * 'a ] -&gt; int = &lt;fun&gt;
488
377
val eval : ([&lt; `Num of int | `Plus of 'a * 'a ] as 'a) -&gt; int = &lt;fun&gt;
489
 
</FONT></PRE>
490
 
To make this even more confortable, you may use type definitions as
 
378
</FONT></PRE><P>To make this even more confortable, you may use type definitions as
491
379
abbreviations for or-patterns. That is, if you have defined <TT>type myvariant = [`Tag1 int | `Tag2 bool]</TT>, then the pattern <TT>#myvariant</TT> is
492
 
equivalent to writing <TT>(`Tag1(_ : int) | `Tag2(_ : bool))</TT>.<BR>
493
 
<BR>
494
 
Such abbreviations may be used alone,
495
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let f = function
 
380
equivalent to writing <TT>(`Tag1(_ : int) | `Tag2(_ : bool))</TT>.</P><P>Such abbreviations may be used alone,
 
381
</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let f = function
496
382
   | #myvariant -&gt; "myvariant"
497
383
   | `Tag3 -&gt; "Tag3";;
498
384
</FONT><FONT COLOR=maroon>val f : [&lt; `Tag1 of int | `Tag2 of bool | `Tag3 ] -&gt; string = &lt;fun&gt;
499
 
</FONT></PRE>
 
385
</FONT></PRE><P>
500
386
or combined with with aliases.
501
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let g1 = function `Tag1 _ -&gt; "Tag1" | `Tag2 _ -&gt; "Tag2";;
 
387
</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let g1 = function `Tag1 _ -&gt; "Tag1" | `Tag2 _ -&gt; "Tag2";;
502
388
</FONT><FONT COLOR=maroon>val g1 : [&lt; `Tag1 of 'a | `Tag2 of 'b ] -&gt; string = &lt;fun&gt;
503
 
&nbsp;
 
389
504
390
<FONT COLOR=black>#</FONT><FONT COLOR=blue>let g = function
505
391
   | #myvariant as x -&gt; g1 x
506
392
   | `Tag3 -&gt; "Tag3";;
507
393
</FONT>val g : [&lt; `Tag1 of int | `Tag2 of bool | `Tag3 ] -&gt; string = &lt;fun&gt;
508
 
</FONT></PRE>
509
 
 
510
 
<H3 CLASS="subsection"><A NAME="htoc42">4.2.1</A>&nbsp;&nbsp;Weaknesses of polymorphic variants</H3>
511
 
After seeing the power of polymorphic variants, one may wonder why
512
 
they were added to core language variants, rather than replacing them.<BR>
513
 
<BR>
514
 
The answer is two fold. One first aspect is that while being pretty
 
394
</FONT></PRE><H3 CLASS="subsection"><A NAME="htoc42">4.2.1</A>��Weaknesses of polymorphic variants</H3><P>After seeing the power of polymorphic variants, one may wonder why
 
395
they were added to core language variants, rather than replacing them.</P><P>The answer is two fold. One first aspect is that while being pretty
515
396
efficient, the lack of static type information allows for less
516
397
optimizations, and makes polymorphic variants slightly heavier than
517
398
core language ones. However noticeable differences would only
518
 
appear on huge data structures.<BR>
519
 
<BR>
520
 
More important is the fact that polymorphic variants, while being
 
399
appear on huge data structures.</P><P>More important is the fact that polymorphic variants, while being
521
400
type-safe, result in a weaker type discipline. That is, core language
522
401
variants do actually much more than ensuring type-safety, they also
523
402
check that you use only declared constructors, that all constructors
524
403
present in a data-structure are compatible, and they enforce typing
525
 
constraints to their parameters.<BR>
526
 
<BR>
527
 
For this reason, you must be more careful about making types explicit
 
404
constraints to their parameters.</P><P>For this reason, you must be more careful about making types explicit
528
405
when you use polymorphic variants. When you write a library, this is
529
406
easy since you can describe exact types in interfaces, but for simple
530
 
programs you are probably better off with core language variants.<BR>
531
 
<BR>
532
 
Beware also that certain idioms make trivial errors very hard to find.
 
407
programs you are probably better off with core language variants.</P><P>Beware also that some idioms make trivial errors very hard to find.
533
408
For instance, the following code is probably wrong but the compiler
534
409
has no way to see it.
535
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>type abc = [`A | `B | `C] ;;
 
410
</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>type abc = [`A | `B | `C] ;;
536
411
</FONT><FONT COLOR=maroon>type abc = [ `A | `B | `C ]
537
 
&nbsp;
 
412
538
413
<FONT COLOR=black>#</FONT><FONT COLOR=blue>let f = function
539
414
   | `As -&gt; "A"
540
415
   | #abc -&gt; "other" ;;
541
416
</FONT>val f : [&lt; `A | `As | `B | `C ] -&gt; string = &lt;fun&gt;
542
 
&nbsp;
 
417
543
418
<FONT COLOR=black>#</FONT><FONT COLOR=blue>let f : abc -&gt; string = f ;;
544
419
</FONT>val f : abc -&gt; string = &lt;fun&gt;
545
 
</FONT></PRE>
 
420
</FONT></PRE><P>
546
421
You can avoid such risks by annotating the definition itself.
547
 
<PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let f : abc -&gt; string = function
 
422
</P><PRE><FONT COLOR=black>#</FONT><FONT COLOR=blue>let f : abc -&gt; string = function
548
423
   | <U>`As</U> -&gt; "A"
549
424
   | #abc -&gt; "other" ;;
550
425
</FONT><FONT COLOR=maroon>Warning U: this match case is unused.
551
426
val f : abc -&gt; string = &lt;fun&gt;
552
 
</FONT></PRE>
553
 
 
554
 
 
555
 
<HR WIDTH="50%" SIZE=1><DL CLASS="list"><DT CLASS="dt-list"><FONT SIZE=5><A NAME="note1" HREF="#text1">1</A></FONT><DD CLASS="dd-list">This correspond to the commuting label mode
 
427
</FONT></PRE><HR CLASS="ffootnoterule"><DL CLASS="thefootnotes"><DT CLASS="dt-thefootnotes">
 
428
<A NAME="note1" HREF="#text1">1</A></DT><DD CLASS="dd-thefootnotes">This correspond to the commuting label mode
556
429
of Objective Caml 3.00 through 3.02, with some additional flexibility
557
430
on total applications. The so-called classic mode (<TT>-nolabels</TT>
558
431
options) is now deprecated for normal use.
559
 
</DL>
 
432
</DD></DL>
560
433
<HR>
561
 
<A HREF="manual005.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
562
 
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
563
 
<A HREF="manual007.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
 
434
<A HREF="manual005.html"><IMG SRC="previous_motif.gif" ALT="Previous"></A>
 
435
<A HREF="index.html"><IMG SRC="contents_motif.gif" ALT="Up"></A>
 
436
<A HREF="manual007.html"><IMG SRC="next_motif.gif" ALT="Next"></A>
564
437
</BODY>
565
438
</HTML>