/[svn]/web/manual/interface.xml
ViewVC logotype

Contents of /web/manual/interface.xml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1217 - (show annotations)
Tue Jul 10 18:32:08 2007 UTC (5 years, 10 months ago) by abate
File MIME type: text/xml
File size: 14034 byte(s)
[r2004-07-05 13:48:09 by afrisch] bigint

Original author: afrisch
Date: 2004-07-05 13:48:10+00:00
1 <?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
2 <!DOCTYPE page [
3 <!ENTITY rarr "&#8594;"> <!-- rightwards arrow, U+2192 ISOnum -->
4 ]>
5 <page name="manual_interfacewithocaml">
6
7 <title>Interfacing CDuce with OCaml</title>
8
9 <box title="Introduction" link="intro">
10
11 <p>
12 This page describes the CDuce/OCaml interface. This interface allows
13 the programmer to:
14 </p>
15 <ul>
16 <li>call OCaml functions from a CDuce module;</li>
17 <li>export a CDuce model as an OCaml module, by giving it an explicit OCaml signature.</li>
18 </ul>
19
20 <p>
21 The intended usages for the interface are:
22 </p>
23 <ul>
24 <li>Piggyback existing OCaml libraries, such as database,
25 network, GUI, data structures;</li>
26 <li>Use CDuce as an XML layer (input/output/transformation) for OCaml
27 projects;</li>
28 <li>Develop fully mixed OCaml/CDuce projects.</li>
29 </ul>
30
31 <p>
32 To see how to build CDuce with support for the OCaml interface,
33 see the <a href="INSTALL">INSTALL</a> file from the CDuce distribution.
34 </p>
35
36
37 </box>
38
39 <box title="Translating types" link="transl">
40
41 <p>
42 The heart of the interface is a mapping from OCaml types to CDuce
43 types. An OCaml type <code>%%t%%</code> is translated to a CDuce type
44 <code>T(%%t%%)</code>, which is meant to be isomorphic to <code>%%t%%</code>:
45 there is a canonical function <code>%%t%%</code> &rarr; <code>T(%%t%%)</code>
46 from OCaml values of type <code>%%t%%</code> to CDuce values of type
47 <code>T(%%t%%)</code>, and another canonical function <code>T(%%t%%)</code> &rarr; <code>%%t%%</code>.
48 </p>
49
50 <ul>
51 <li>
52 Basic OCaml types <code>char</code>, <code>int</code>, <code>string</code>,
53 <code>unit</code> are translated respectively to
54 <code>Byte = '\0;'--'\255;'</code>, <code>-1073741824 --
55 1073741823</code>, <code>Latin1 = [ Byte* ]</code>, <code>[] = `nil</code>.
56 </li>
57
58 <li>
59 Tuple types <code>%%t%%1 * ... * %%t%%n</code> are translated to nested CDuce
60 product types <code>(T(%%t%%1),(...,T(%%t%%n))...)</code>. A function type
61 <code>%%t%% -> %%s%%</code> is translated to <code>T(%%t%%) -> T(%%s%%)</code>.
62 Labels and optional labels on the argument of the arrow are discarded.
63 </li>
64
65 <li>
66 A list type <code>%%t%% list</code> is translated to an homogeneous
67 sequence type <code>[ T(%%t%%)* ]</code>. An array type
68 <code>%%t%% array</code> has the same translation.
69 </li>
70
71 <li>
72 A variant type with a declaration <code>A1 of %%t%%1 | ... | An of
73 %%t%%n</code> is translated to a type <code>(`A1,T(%%t%%1)) | ... |
74 (`An,T(%%t%%n))</code>. If a constructor <code>Ai</code> has no argument, the resulting
75 term is <code>`Ai</code>, not <code>(`Ai,[])</code>.
76 Polymorphic variant types are treated similarly.
77 </li>
78
79 <li>
80 A record type with a declaration <code>{ l1 : %%t%%1; ...; ln : %%t%%n
81 }</code> is translated to a closed record type <code>{| l1 = T(%%t%%1);
82 ... ; ln = T(%%t%%n) |}</code>. Mutable fields are just copied.
83 </li>
84
85 <li>
86 Private variant and record types are treated correctly: the interface
87 never tries to generate OCaml values of these types, but it will happily
88 translate them to CDuce values.
89 </li>
90
91 <li>
92 A reference type <code>%%t%% ref</code> is translated to the CDuce
93 reference type <code>ref T(%%t%%)</code>. When converting a Caml reference
94 to CDuce, the operation (set,get) on the resulting reference refers
95 to the original reference. However, when converting a CDuce reference
96 to OCaml, the content of the reference is fetched (set), and a fresh
97 OCaml reference is created (copy semantics).
98 </li>
99
100 <li>
101 The type <code>Cduce_lib.Value.t</code> is translated to the CDuce
102 type <code>Any</code>. The corresponding translation functions are the
103 identity. This can be used to avoid multiple copies when translating
104 a complex value back and forth between CDuce and OCaml.
105 The type <code>Cduce_lib.Encodings.Utf8.t</code> is translated to the CDuce
106 type <code>String</code>.
107 The type <code>Big_int.big_int</code> is translated to the CDuce
108 type <code>Int</code>.
109 </li>
110
111 <li>
112 A <em>monomorphic</em> abstract type <code>t</code> is translated to
113 the CDuce type <code>!t</code>. This type just acts as a container for
114 values of the abstract type. CDuce never produces a value of this
115 type, and it cannot inspect the content of such a value (apart
116 from checking its type).
117 </li>
118 </ul>
119
120 <p>
121 The canonical translation is summarized in the following box:
122 </p>
123
124
125 <table border="1" style="align:middle">
126 <tr>
127 <th>OCaml type <tt><i>t</i></tt></th>
128 <th>CDuce type <tt>T(<i>t</i>)</tt></th>
129 </tr>
130 <tr><td><tt>char</tt></td><td><tt>Byte = '\0;'--'\255;'</tt></td></tr>
131 <tr><td><tt>int</tt></td><td><tt>-1073741824 -- 1073741823</tt></td></tr>
132 <tr><td><tt>string</tt></td><td><tt>Latin1 = [ Byte* ]</tt></td></tr>
133 <tr><td><tt>unit</tt></td><td><tt>[] = `nil</tt></td></tr>
134 <tr><td><tt>bool</tt></td><td><tt>Bool = `true | `false</tt></td></tr>
135
136 <tr><td><tt><i>t1</i> * ... * <i>tn</i></tt></td>
137 <td><tt>(T(<i>t1</i>),(...,T(<i>tn</i>))...)</tt></td></tr>
138
139 <tr><td><tt><i>t</i> -> <i>s</i></tt></td>
140 <td><tt>T(<i>t</i>) -> T(<i>s</i>)</tt></td></tr>
141
142 <tr><td><tt><i>t</i> list</tt></td>
143 <td><tt>[ T(<i>t</i>)* ]</tt></td></tr>
144
145 <tr><td><tt><i>t</i> array</tt></td>
146 <td><tt>[ T(<i>t</i>)* ]</tt></td></tr>
147
148 <tr><td><tt>A of <i>t</i> | B of <i>s</i> | C</tt></td>
149 <td><tt>(`A, T(<i>t</i>)) | (`B, T(<i>s</i>)) | `C</tt></td></tr>
150
151 <tr><td><tt>[ `A of <i>t</i> | `B of <i>s</i> | `C ]</tt></td>
152 <td><tt>(`A, T(<i>t</i>)) | (`B, T(<i>s</i>)) | `C</tt></td></tr>
153
154 <tr><td><tt>{ x : <i>t</i>; y : <i>s</i> }</tt></td>
155 <td><tt>{| x = T(<i>t</i>); y = T(<i>s</i>) |}</tt></td></tr>
156
157 <tr><td><tt><i>t</i> ref</tt></td>
158 <td><tt>ref T(<i>t</i>)</tt></td></tr>
159
160 <tr><td><tt>Cduce_lib.Value.t</tt></td><td><tt>Any</tt></td></tr>
161 <tr><td><tt>Cduce_lib.Encodings.Utf8.t</tt></td><td><tt>String</tt></td></tr>
162 <tr><td><tt>Big_int.big_int</tt></td><td><tt>Int</tt></td></tr>
163 </table>
164
165 <p>
166 Only monomorphic types are handled by the interface. It is allowed to
167 use polymorphic constructors as an intermediate, as long as the final
168 type to be translated is monomorphic. Recursive types, including
169 unguarded ones (option <code>-rectypes</code> of the OCaml compiler)
170 are accepted. In the following example:
171 </p>
172
173 <sample>
174 type 'a t = A of int | B of 'a t
175 type s = int t
176
177 type 'a u = A of ('a * 'a) u | B
178 type v = int u
179 </sample>
180
181 <p>
182 the type <code>s</code> can be translated, but the type <code>v</code>
183 can't, because its infinite unfolding is not a regular type.
184 </p>
185
186 <p>
187 OCaml object types are not supported.
188 </p>
189
190 <p>
191 Note that values are copied in depth (until reaching an abstract type,
192 a function types, etc...). In particular, translating an OCaml cyclic
193 values to CDuce will not terminate (well, with a stack overflow!).
194 </p>
195
196 </box>
197
198 <box title="Calling OCaml from CDuce" link="call_ocaml">
199
200 <p>
201 If an OCaml value has a type that can be translated, it is possible to
202 use it from CDuce (see the <a href="#link">How to compile and link</a> section for
203 more details).
204 </p>
205
206 <p>
207 In a CDuce module, you can write <code>external "M.f"</code>
208 to denote the result of translating the OCaml value <code>M.f</code>
209 to CDuce. Actually, you can simply write <code>M.f</code>.
210 </p>
211
212 <p>
213 If the value you want to use has a polymorphic type, you can make
214 the translation work by explicitly instantiating its type
215 variables with CDuce types. The syntax is <code>external { "M.f" t1
216 ... tn }</code> where the <code>ti</code> are CDuce types. The type
217 variables are listed in the order they appear in a left-to-right
218 reading of the OCaml type. Example:
219 </p>
220
221 <sample>
222 let listmap = external { "List.map" Int String }
223 </sample>
224
225 <p>
226 will return a function of type <code>(Int -> String) -> ([Int*] -> [String*])</code>
227 </p>
228
229 </box>
230
231 <box title="Calling CDuce from OCaml" link="call_cduce">
232
233 <p>
234 We have seen in the section above how OCaml values can be used from a
235 CDuce module. It is also possible to use CDuce values from OCaml. To
236 do so, you must give an OCaml interface (.mli) for the CDuce module
237 (.cdo). The interface can define arbitrary types, and declare
238 monomorphic values. These values must be defined in the CDuce module
239 with a compatible type (subtype of the translation).
240 </p>
241
242 <p>
243 As an example, suppose you have this CDuce module (foo.cd):
244 </p>
245
246 <sample>
247 type s = (`A,int) | `B
248 let double (x : Latin1) : Latin1 = x @ x
249 let dump (x : s) : Latin1 = string_of x
250 </sample>
251
252 <p>
253 You can define an OCaml interface for it (foo.mli):
254 </p>
255
256 <sample>
257 type t = A of int | B
258 val double: string -> string
259 val dump: t -> string
260 </sample>
261
262 <p>
263 When the foo.cdo module is compiled, CDuce will look for the foo.cmi
264 compiled interface (hence, you must first compile it yourself with
265 OCaml), and generate stub code, so as to define an OCaml module
266 <code>Foo</code> with the given interface. This module can then be
267 linked together with other "regular" OCaml modules, and used from them.
268 </p>
269
270 <p>
271 Notes:
272 </p>
273
274 <ul>
275 <li>
276 It is not mandatory to export all the values of the CDuce module in
277 the OCaml interface.
278 </li>
279 <li>
280 The types defined in the interface cannot (currently) be used
281 within the CDuce module.
282 </li>
283 </ul>
284
285 </box>
286
287 <box title="How to compile and link" link="link">
288
289 <p>
290 Here is the protocol to compile a single CDuce module:
291 </p>
292
293 <ul>
294 <li>
295 Create a <code>.cmi</code> from your OCaml file with
296 <code>ocamlc -c foo.mli</code>.
297 </li>
298 <li>
299 Compile your CDuce file <code>cduce --compile foo.cd</code>. This command
300 will create a CDuce bytecode file <code>foo.cdo</code>, which
301 also contains the OCaml glue code to export CDuce values as OCaml
302 ones, and to bind OCaml values used within the CDuce module.
303 </li>
304 <li>
305 Compile the OCaml glue code
306 <code>ocamlfind ocamlc -c -package cduce -pp cdo2ml -impl foo.cdo</code>.
307 The<code>cdo2ml</code> tool extracts the OCaml glue code from the
308 CDuce bytecode file.
309 </li>
310 </ul>
311
312 <p>
313 You can then link the resulting OCaml module, maybe with other
314 modules (either regular ones, or wrapping a CDuce module):
315 <code>ocamlfind ocamlc -o {{...}} -package cduce -linkpkg foo.cmo {{...}}</code>.
316 When the program is run, the CDuce bytecode file
317 <code>foo.cdo</code> is looked in the <em>current directory</em>
318 only, and loaded dynamically (with a checksum test).
319 </p>
320
321 <p>
322 It might be preferable to include the CDuce bytecode directly into
323 the OCaml glue code. You can do this by giving <code>cdo2ml</code>
324 the <code>-static</code> option:
325 <code>ocamlfind ocamlc -c -package cduce -pp "cdo2ml -static" -impl foo.cdo</code>.
326 Modules which have been compiled this way don't need the
327 corresponding <code>.cdo</code> at runtime.
328 </p>
329
330 <p>
331 If you choose static linking, you have to use a correct ordering
332 when linking with OCaml. Note that it is possible to mix static and
333 dynamic linking for various CDuce modules in a same program.
334 </p>
335
336 <p>
337 Everything works <i>mutatis mutandis</i> with the native OCaml compiler ocamlopt.
338 </p>
339
340 <p>
341 You might need to pass extra <code>-I</code> flags to CDuce so that
342 it could find the referenced <code>.cmi</code> files.
343 </p>
344
345 <p>
346 It is possible to run a CDuce module with <code>cduce --run
347 foo.cdo</code>, but only if it doesn't use OCaml values.
348 </p>
349
350 <p>
351 Interested users can look at the output of <code>cdo2ml</code> to
352 better understand how the interface works.
353 </p>
354
355 </box>
356
357 <box title="Examples" link="examples">
358
359 <section title="Getting the value of an environment variable">
360
361 <sample>
362 let home = Sys.getenv "home";;
363 </sample>
364
365 </section>
366
367 <section title="Ejecting your CD with CDuce">
368
369 <p>
370 This example demonstrates how to use OCamlSDL library.
371 </p>
372
373 <sample>
374 Sdl.init `None [ `EVERYTHING ];;
375 let cd = Sdlcdrom.cd_open 0;;
376 Sdlcdrom.cd_eject cd;;
377 </sample>
378
379 <p>
380 If you put these lines in a file <code>cdsdl.cd</code>, you can
381 compile and link it with:
382 </p>
383
384 <sample>
385 cduce --compile cdsdl.cd -I `ocamlfind query ocamlsdl`
386 ocamlfind ocamlc -o cdsdl -pp "cdo2ml -static" -impl cdsdl.cdo \
387 -package cduce,ocamlsdl -linkpkg
388 </sample>
389
390
391 </section>
392
393 <section title="Accessing MySQL">
394
395 <p>
396 This example demonstrates how to use ocaml-mysql library.
397 </p>
398
399 <sample>
400 let db = Mysql.connect Mysql.defaults;;
401
402 match Mysql.list_dbs db `None [] with
403 | (`Some,l) -> print [ 'Databases: ' !(string_of l) '\n' ]
404 | `None -> [];;
405
406 print [
407 'Client info: ' !(Mysql.client_info []) '\n'
408 'Host info: ' !(Mysql.host_info db) '\n'
409 'Server info: ' !(Mysql.server_info db) '\n'
410 'Proto info: ' !(string_of (Mysql.proto_info db)) '\n'
411 ];;
412 </sample>
413
414 <p>
415 If you put these lines in a file <code>cdmysql.cd</code>, you can
416 compile and link it with:
417 </p>
418
419 <sample>
420 cduce --compile cdmysql.cd -I `ocamlfind query mysql`
421 ocamlfind ocamlc -o cdmysql -pp "cdo2ml -static" -impl cdmysql.cdo \
422 -package cduce,mysql -linkpkg
423 </sample>
424
425 </section>
426
427
428
429 <section title="Evaluating CDuce expressions">
430
431 <p>
432 This example demonstrates how to dynamically compile
433 and evaluate CDuce programs contained in a string.
434 </p>
435
436 <sample>
437 <![CDATA[
438 let pr = Cduce_lib.Value.print_utf8
439
440 try
441 let l = Cduce_lib.Cduce.eval
442 "let fun f (x : Int) : Int = x + 1;;
443 let fun g (x : Int) : Int = 2 * x;;
444 f;; g;;
445 let a = g (f 10);;
446 "
447 in
448 transform l with
449 | ((`Some,id),v) ->
450 pr [ !id ' = ' !(string_of v) '\n' ]
451 | (`None, f & (Int -> Int)) ->
452 pr [ !(string_of (f 100)) '\n' ]
453 | (`None,v) ->
454 pr [ !(string_of v) '\n' ]
455 with (exn & Latin1) ->
456 print [ 'Exception: ' !exn '\n' ]
457 ]]>
458 </sample>
459
460 <p>
461 If you put these lines in a file <code>eval.cd</code>, you can
462 compile and link it with:
463 </p>
464
465 <sample>
466 cduce --compile eval.cd -I `ocamlfind query cduce`
467 ocamlfind ocamlc -o eval -pp "cdo2ml -static" -impl eval.cdo \
468 -package cduce -linkpkg
469 </sample>
470
471 </section>
472
473 <section title="Use CDuce to compute the factorial on big integers">
474
475 <sample>
476 (* File cdnum.mli: *)
477
478 val fact: Big_int.big_int -> Big_int.big_int
479
480
481 (* File cdnum.cd: *)
482
483 let aux ((Int,Int) -> Int)
484 | (x, 0 | 1) -> x
485 | (x, n) -> aux (x * n, n - 1)
486
487 let fact (x : Int) : Int = aux (Big_int.unit_big_int, x)
488 (* Could write 1 instead of Big_int.unit_big_int. Just for fun. *)
489
490 </sample>
491
492 </section>
493
494 </box>
495
496 </page>

CVS Admin">CVS Admin
ViewVC Help
Powered by ViewVC 1.1.5