File: manual019.html

package info (click to toggle)
ocaml-doc 2.04-2
  • links: PTS
  • area: main
  • in suites: potato
  • size: 2,820 kB
  • ctags: 997
  • sloc: makefile: 38; sh: 12
file content (242 lines) | stat: -rw-r--r-- 16,722 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
            "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset= ISO-8859-1">
<TITLE>
 Language extensions
</TITLE>
</HEAD>
<BODY >
<A HREF="manual006.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="manual020.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<HR>

<H1>Chapter&nbsp;6:&nbsp;&nbsp; Language extensions</H1> <A NAME="c:extensions"></A>
This chapter describes the language features that are implemented in
Objective Caml, but not described in the Objective Caml
reference manual. In contrast with the fairly stable kernel language
that is described in the reference manual, the extensions presented
here are still experimental, and may be removed or changed in the
future.<BR>
<BR>

<H2>6.1&nbsp;&nbsp; Streams and stream parsers</H2>
<A NAME="s:streams"></A>Objective Caml comprises a library type for <I>streams</I>
(possibly infinite sequences of elements, that are evaluated on
demand), and associated stream expressions, to build streams, and
stream patterns, to destructure streams. Streams and stream patterns
provide a natural approach to the writing of recursive-descent
parsers.<BR>
<BR>
Streams are presented by the following extensions to the syntactic
classes of expressions:<A NAME="@manual.kwd157"></A><BR>
<BR>

<A NAME="@manual.kwd158"></A>
<A NAME="@manual.kwd159"></A><BR>
<BR>
<DIV ALIGN=center>
<TABLE CELLSPACING=2 CELLPADDING=0>
<TR><TD  ALIGN=right NOWRAP>
<TT><I><FONT COLOR=maroon>expr</FONT></I></TT></TD>
<TD  ALIGN=right NOWRAP>::=</TD>
<TD  ALIGN=left NOWRAP>
 ...</TD>
</TR>
<TR><TD  ALIGN=right NOWRAP>&nbsp;</TD>
<TD  ALIGN=right NOWRAP>|</TD>
<TD  ALIGN=left NOWRAP> <TT><FONT COLOR=blue>[&lt;</FONT></TT> <TT><FONT COLOR=blue>&gt;]</FONT></TT></TD>
</TR>
<TR><TD  ALIGN=right NOWRAP>&nbsp;</TD>
<TD  ALIGN=right NOWRAP>|</TD>
<TD  ALIGN=left NOWRAP> <TT><FONT COLOR=blue>[&lt;</FONT></TT> <TT><I><FONT COLOR=maroon>stream-component</FONT></I></TT> &nbsp;{ <TT><FONT COLOR=blue>;</FONT></TT> <TT><I><FONT COLOR=maroon>stream-component</FONT></I></TT> } <TT><FONT COLOR=blue>&gt;]</FONT></TT></TD>
</TR>
<TR><TD  ALIGN=right NOWRAP>&nbsp;</TD>
<TD  ALIGN=right NOWRAP>|</TD>
<TD  ALIGN=left NOWRAP> <TT><FONT COLOR=blue>parser</FONT></TT> [<TT><I><FONT COLOR=maroon>pattern</FONT></I></TT>] &nbsp;<TT><I><FONT COLOR=maroon>stream-matching</FONT></I></TT></TD>
</TR>
<TR><TD  ALIGN=right NOWRAP>&nbsp;</TD>
<TD  ALIGN=right NOWRAP>|</TD>
<TD  ALIGN=left NOWRAP> <TT><FONT COLOR=blue>match</FONT></TT> <TT><I><FONT COLOR=maroon>expr</FONT></I></TT> <TT><FONT COLOR=blue>with</FONT></TT> <TT><FONT COLOR=blue>parser</FONT></TT> &nbsp;[<TT><I><FONT COLOR=maroon>pattern</FONT></I></TT>] &nbsp;<TT><I><FONT COLOR=maroon>stream-matching</FONT></I></TT></TD>
</TR>
<TR><TD  ALIGN=right NOWRAP>
<TT><I><FONT COLOR=maroon>stream-component</FONT></I></TT></TD>
<TD  ALIGN=right NOWRAP>::=</TD>
<TD  ALIGN=left NOWRAP>
 <TT><FONT COLOR=blue>'</FONT></TT> <TT><I><FONT COLOR=maroon>expr</FONT></I></TT></TD>
</TR>
<TR><TD  ALIGN=right NOWRAP>&nbsp;</TD>
<TD  ALIGN=right NOWRAP>|</TD>
<TD  ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>expr</FONT></I></TT></TD>
</TR>
<TR><TD  ALIGN=right NOWRAP>
<TT><I><FONT COLOR=maroon>stream-matching</FONT></I></TT></TD>
<TD  ALIGN=right NOWRAP>::=</TD>
<TD  ALIGN=left NOWRAP>
 <TT><I><FONT COLOR=maroon>stream-pattern</FONT></I></TT> &nbsp;[<TT><I><FONT COLOR=maroon>pattern</FONT></I></TT>] <TT><FONT COLOR=blue>-&gt;</FONT></TT> &nbsp;<TT><I><FONT COLOR=maroon>expr</FONT></I></TT>
 &nbsp;{ <TT><FONT COLOR=blue>|</FONT></TT> <TT><I><FONT COLOR=maroon>stream-pattern</FONT></I></TT> &nbsp;[<TT><I><FONT COLOR=maroon>pattern</FONT></I></TT>] <TT><FONT COLOR=blue>-&gt;</FONT></TT> &nbsp;<TT><I><FONT COLOR=maroon>expr</FONT></I></TT> }</TD>
</TR>
<TR><TD  ALIGN=right NOWRAP>
<TT><I><FONT COLOR=maroon>stream-pattern</FONT></I></TT></TD>
<TD  ALIGN=right NOWRAP>::=</TD>
<TD  ALIGN=left NOWRAP>
 <TT><FONT COLOR=blue>[&lt;</FONT></TT> <TT><FONT COLOR=blue>&gt;]</FONT></TT></TD>
</TR>
<TR><TD  ALIGN=right NOWRAP>&nbsp;</TD>
<TD  ALIGN=right NOWRAP>|</TD>
<TD  ALIGN=left NOWRAP> <TT><FONT COLOR=blue>[&lt;</FONT></TT> <TT><I><FONT COLOR=maroon>stream-pat-comp</FONT></I></TT> &nbsp;{ <TT><FONT COLOR=blue>;</FONT></TT> <TT><I><FONT COLOR=maroon>stream-pat-comp</FONT></I></TT> &nbsp;[ <TT><FONT COLOR=blue>?</FONT></TT> <TT><I><FONT COLOR=maroon>expr</FONT></I></TT> ] }<TT><FONT COLOR=blue>&gt;]</FONT></TT></TD>
</TR>
<TR><TD  ALIGN=right NOWRAP>
<TT><I><FONT COLOR=maroon>stream-pat-comp</FONT></I></TT></TD>
<TD  ALIGN=right NOWRAP>::=</TD>
<TD  ALIGN=left NOWRAP>
 <TT><FONT COLOR=blue>'</FONT></TT> <TT><I><FONT COLOR=maroon>pattern</FONT></I></TT> &nbsp;[ <TT><FONT COLOR=blue>when</FONT></TT> <TT><I><FONT COLOR=maroon>expr</FONT></I></TT> ]</TD>
</TR>
<TR><TD  ALIGN=right NOWRAP>&nbsp;</TD>
<TD  ALIGN=right NOWRAP>|</TD>
<TD  ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>pattern</FONT></I></TT> <TT><FONT COLOR=blue>=</FONT></TT> &nbsp;<TT><I><FONT COLOR=maroon>expr</FONT></I></TT></TD>
</TR>
<TR><TD  ALIGN=right NOWRAP>&nbsp;</TD>
<TD  ALIGN=right NOWRAP>|</TD>
<TD  ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>ident</FONT></I></TT></TD>
</TR></TABLE></DIV><BR>
Stream expressions are bracketed by <CODE>[&lt;</CODE> and <CODE>&gt;]</CODE>. They
represent the concatenation of their components. The component
<TT><FONT COLOR=blue>'</FONT></TT> <TT><I><FONT COLOR=maroon>expr</FONT></I></TT> represents the one-element stream whose element is the
value of <TT><I><FONT COLOR=maroon>expr</FONT></I></TT>. The component <TT><I><FONT COLOR=maroon>expr</FONT></I></TT> represents a
sub-stream. For instance, if both <TT>s</TT> and <TT>t</TT> are streams of integers,
then <CODE>[&lt;'1; s; t; '2&gt;]</CODE> is a stream of integers containing the
element <TT>1</TT>, then the elements of <TT>s</TT>, then those of <TT>t</TT>, and finally
<TT>2</TT>. The empty stream is denoted by <CODE>[&lt; &gt;]</CODE>.<BR>
<BR>
Unlike any other kind of expressions in the language, stream
expressions are submitted to lazy evaluation: the components are not
evaluated when the stream is built, but only when they are accessed
during stream matching. The components are evaluated once, the first
time they are accessed; the following accesses reuse the value
computed the first time.<BR>
<BR>
Stream patterns, also bracketed by <CODE>[&lt;</CODE> and <CODE>&gt;]</CODE>, describe
initial segments of streams. In particular, the stream pattern
<CODE>[&lt; &gt;]</CODE> matches all streams. Stream pattern components are
matched against the corresponding elements of a stream. The component
<TT><FONT COLOR=blue>'</FONT></TT> <TT><I><FONT COLOR=maroon>pattern</FONT></I></TT> matches the corresponding stream element against the
pattern; if followed by <TT><I><FONT COLOR=maroon>when</FONT></I></TT>, the match is accepted only if the
result of the guard expression is <TT>true</TT>. The component <TT><I><FONT COLOR=maroon>pattern</FONT></I></TT> <TT><FONT COLOR=blue>=</FONT></TT>
&nbsp;<TT><I><FONT COLOR=maroon>expr</FONT></I></TT> applies the function denoted by <TT><I><FONT COLOR=maroon>expr</FONT></I></TT> to the current stream,
then matches the result of the function against <TT><I><FONT COLOR=maroon>pattern</FONT></I></TT>. Finally,
the component <TT><I><FONT COLOR=maroon>ident</FONT></I></TT> simply binds the identifier to the stream being
matched.<BR>
<BR>
Stream matching proceeds destructively: once a component has been
matched, it is discarded from the stream (by in-place modification).<BR>
<BR>
Stream matching proceeds in two steps: first, a pattern is selected by
matching the stream against the first components of the stream
patterns; then, the following components of the selected pattern are
checked against the stream. If the following components do not match,
the exception <TT>Stream.Error</TT> is raised. There is no backtracking
here: stream matching commits to the pattern selected according to the
first element. If none of the first components of the stream patterns
match, the exception <TT>Stream.Failure</TT> is raised. The
<TT>Stream.Parse</TT><TT>_</TT><TT>failure</TT> exception causes the next alternative to be
tried, if it occurs during the matching of the first element of a
stream, before matching has committed to one pattern.<BR>
<BR>
The streams hold the count of their elements discarded. The optional
<TT><I><FONT COLOR=maroon>pattern</FONT></I></TT> before the first stream pattern is bound to the stream
count before the matching. The one after each stream pattern
(optional, too) is bound to the stream count after the matching.<BR>
<BR>
The exception <TT>Parse</TT><TT>_</TT><TT>error</TT> has a string parameter coming from the
optional <TT><FONT COLOR=blue>?</FONT></TT> <TT><I><FONT COLOR=maroon>expr</FONT></I></TT> after the stream pattern components (its default
is the empty string). This expression is evaluated only in case of
error.<BR>
<BR>
See <EM>Functional programming using Caml Light</EM> for a more gentle
introductions to streams, and for some examples of their use in
writing parsers. A more formal presentation of streams, and a
discussion of alternate semantics, can be found in <EM>Parsers in ML</EM>
by Michel Mauny and Daniel de Rauglaudre, in the proceedings of the
1992 ACM conference on Lisp and Functional Programming.<BR>
<BR>

<H2>6.2&nbsp;&nbsp; Range patterns</H2>In patterns, Objective Caml recognizes the form
<TT><FONT COLOR=blue>'</FONT></TT> <TT><I><FONT COLOR=maroon>c</FONT></I></TT> <TT><FONT COLOR=blue>'</FONT></TT> <TT><FONT COLOR=blue>..</FONT></TT> <TT><FONT COLOR=blue>'</FONT></TT> &nbsp;<TT><I><FONT COLOR=maroon>d</FONT></I></TT> <TT><FONT COLOR=blue>'</FONT></TT>
(two character literals separated by&nbsp;<TT>..</TT>) as shorthand for the pattern
<DIV ALIGN=center>
<TT><FONT COLOR=blue>'</FONT></TT> <TT><I><FONT COLOR=maroon>c</FONT></I></TT> <TT><FONT COLOR=blue>'</FONT></TT> <TT><FONT COLOR=blue>|</FONT></TT> <TT><FONT COLOR=blue>'</FONT></TT> &nbsp;<TT><I><FONT COLOR=maroon>c</FONT></I></TT><SUB><FONT SIZE=2>1</FONT></SUB> <TT><FONT COLOR=blue>'</FONT></TT> <TT><FONT COLOR=blue>|</FONT></TT> <TT><FONT COLOR=blue>'</FONT></TT> &nbsp;<TT><I><FONT COLOR=maroon>c</FONT></I></TT><SUB><FONT SIZE=2>2</FONT></SUB> <TT><FONT COLOR=blue>'</FONT></TT> <TT><FONT COLOR=blue>|</FONT></TT> ...
 <TT><FONT COLOR=blue>|</FONT></TT> <TT><FONT COLOR=blue>'</FONT></TT> &nbsp;<TT><I><FONT COLOR=maroon>c</FONT></I></TT><SUB><FONT SIZE=2><I>n</I></FONT></SUB> <TT><FONT COLOR=blue>'</FONT></TT> <TT><FONT COLOR=blue>|</FONT></TT> <TT><FONT COLOR=blue>'</FONT></TT> &nbsp;<TT><I><FONT COLOR=maroon>d</FONT></I></TT> <TT><FONT COLOR=blue>'</FONT></TT>
</DIV>
where <I>c</I><SUB><FONT SIZE=2>1</FONT></SUB>, <I>c</I><SUB><FONT SIZE=2>2</FONT></SUB>, ..., <I>c</I><SUB><FONT SIZE=2><I>n</I></FONT></SUB> are the characters
that occur between <I>c</I> and <I>d</I> in the ASCII character set. For
instance, the pattern <TT>'0'..'9'</TT> matches all characters that are digits.<BR>
<BR>

<H2>6.3&nbsp;&nbsp; Assertion checking</H2>
<A NAME="@manual.kwd160"></A>Objective Caml supports the <TT>assert</TT> construct to check debugging assertions.
The expression <TT><FONT COLOR=blue>assert</FONT></TT> <TT><I><FONT COLOR=maroon>expr</FONT></I></TT> evaluates the expression <TT><I><FONT COLOR=maroon>expr</FONT></I></TT> and
returns <TT>()</TT> if <TT><I><FONT COLOR=maroon>expr</FONT></I></TT> evaluates to <TT>true</TT>. Otherwise, the exception
<TT>Assert</TT><TT>_</TT><TT>failure</TT> is raised with the source file name and the
location of <TT><I><FONT COLOR=maroon>expr</FONT></I></TT> as arguments. Assertion
checking can be turned off with the <TT>-noassert</TT> compiler option.<BR>
<BR>
As a special case, <TT>assert false</TT> is reduced to
<TT>raise (Assert</TT><TT>_</TT><TT>failure ...)</TT>, which is polymorphic (and
is not turned off by the <TT>-noassert</TT> option).
<A NAME="@manual3"></A><BR>
<BR>

<H2>6.4&nbsp;&nbsp; Deferred computations</H2>
<A NAME="@manual.kwd161"></A>The expression <TT><FONT COLOR=blue>lazy</FONT></TT> <TT><I><FONT COLOR=maroon>expr</FONT></I></TT> returns a value <I>v</I> of type <TT>Lazy.t</TT> that
encapsulates the computation of <TT><I><FONT COLOR=maroon>expr</FONT></I></TT>. The argument <TT><I><FONT COLOR=maroon>expr</FONT></I></TT> is not
evaluated at this point in the program. Instead, its evaluation will
be performed the first time <TT>Lazy.force</TT> is applied to the value
<I>v</I>, returning the actual value of <TT><I><FONT COLOR=maroon>expr</FONT></I></TT>. Subsequent applications
of <TT>Lazy.force</TT> to <I>v</I> do not evaluate <TT><I><FONT COLOR=maroon>expr</FONT></I></TT> again.<BR>
<BR>
The expression <TT><FONT COLOR=blue>lazy</FONT></TT> <TT><I><FONT COLOR=maroon>expr</FONT></I></TT> is equivalent to
<TT><FONT COLOR=blue>ref</FONT></TT>(<TT><FONT COLOR=blue>Lazy.Delayed</FONT></TT>(<TT><FONT COLOR=blue>fun</FONT></TT> <TT><FONT COLOR=blue>()</FONT></TT> <TT><FONT COLOR=blue>-&gt;</FONT></TT> <TT><I><FONT COLOR=maroon>expr</FONT></I></TT>)).
For more information, see the description of module <TT>Lazy</TT> in the
standard library (section&nbsp;<A HREF="manual042.html#s:Lazy">17.12</A>).
<A NAME="@manual4"></A><A NAME="@manual5"></A><BR>
<BR>

<H2>6.5&nbsp;&nbsp; Record copy with update</H2>
<A NAME="@manual.kwd162"></A>The expression
<TT><FONT COLOR=blue>{</FONT></TT> <TT><I><FONT COLOR=maroon>expr</FONT></I></TT> <TT><FONT COLOR=blue>with</FONT></TT> &nbsp;<TT><I><FONT COLOR=maroon>lbl</FONT></I></TT><SUB><FONT SIZE=2>1</FONT></SUB> <TT><FONT COLOR=blue>=</FONT></TT> &nbsp;<TT><I><FONT COLOR=maroon>expr</FONT></I></TT><SUB><FONT SIZE=2>1</FONT></SUB> <TT><FONT COLOR=blue>;</FONT></TT> ... <TT><FONT COLOR=blue>;</FONT></TT> &nbsp;<TT><I><FONT COLOR=maroon>lbl</FONT></I></TT><SUB><FONT SIZE=2><I>n</I></FONT></SUB> <TT><FONT COLOR=blue>=</FONT></TT> &nbsp;<TT><I><FONT COLOR=maroon>expr</FONT></I></TT><SUB><FONT SIZE=2><I>n</I></FONT></SUB> <TT><FONT COLOR=blue>}</FONT></TT>
builds a fresh record with fields <TT><I><FONT COLOR=maroon>lbl</FONT></I></TT><SUB><FONT SIZE=2>1</FONT></SUB> ... &nbsp;<TT><I><FONT COLOR=maroon>lbl</FONT></I></TT><SUB><FONT SIZE=2><I>n</I></FONT></SUB> equal to
<TT><I><FONT COLOR=maroon>expr</FONT></I></TT><SUB><FONT SIZE=2>1</FONT></SUB> ... &nbsp;<TT><I><FONT COLOR=maroon>expr</FONT></I></TT><SUB><FONT SIZE=2><I>n</I></FONT></SUB>, and all other fields having the same value as
in the record <TT><I><FONT COLOR=maroon>expr</FONT></I></TT>. In other terms, it returns a shallow copy of
the record <TT><I><FONT COLOR=maroon>expr</FONT></I></TT>, except for the fields <TT><I><FONT COLOR=maroon>lbl</FONT></I></TT><SUB><FONT SIZE=2>1</FONT></SUB> ... &nbsp;<TT><I><FONT COLOR=maroon>lbl</FONT></I></TT><SUB><FONT SIZE=2><I>n</I></FONT></SUB>,
which are initialized to <TT><I><FONT COLOR=maroon>expr</FONT></I></TT><SUB><FONT SIZE=2>1</FONT></SUB> ... &nbsp;<TT><I><FONT COLOR=maroon>expr</FONT></I></TT><SUB><FONT SIZE=2><I>n</I></FONT></SUB>. For example:
<PRE>
        type point = { x : float; y : float; z : float }
        let proj p = { p with x = 0.0 }
        let proj p = { x = 0.0; y = p.y; z = p.z }
</PRE>
The two definitions of <TT>proj</TT> above are equivalent.<BR>
<BR>

<H2>6.6&nbsp;&nbsp; Local modules</H2>
<A NAME="@manual.kwd163"></A>
<A NAME="@manual.kwd164"></A>The expression
<TT><FONT COLOR=blue>let</FONT></TT> <TT><FONT COLOR=blue>module</FONT></TT> <TT><I><FONT COLOR=maroon>module-name</FONT></I></TT> <TT><FONT COLOR=blue>=</FONT></TT> &nbsp;<TT><I><FONT COLOR=maroon>module-expr</FONT></I></TT> <TT><FONT COLOR=blue>in</FONT></TT> &nbsp;<TT><I><FONT COLOR=maroon>expr</FONT></I></TT>
locally binds the module expression <TT><I><FONT COLOR=maroon>module-expr</FONT></I></TT> to the identifier
<TT><I><FONT COLOR=maroon>module-name</FONT></I></TT> during the evaluation of the expression <TT><I><FONT COLOR=maroon>expr</FONT></I></TT>.
It then returns the value of <TT><I><FONT COLOR=maroon>expr</FONT></I></TT>. For example:
<PRE>
        let remove_duplicates comparison_fun string_list =
          let module StringSet =
            Set.Make(struct type t = string
                            let compare = comparison_fun end) in
          StringSet.elements
            (List.fold_right StringSet.add string_list StringSet.empty)
</PRE><HR>
<A HREF="manual006.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="manual020.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
</BODY>
</HTML>