more renaming into OCaml
git-svn-id: http://caml.inria.fr/svn/ocamldoc/trunk@12146 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02master
parent
53ae65e944
commit
5e8e78b984
|
@ -2,7 +2,7 @@
|
|||
\pdfchapter{Batch compilation (ocamlc)}
|
||||
|
||||
This chapter describes the OCaml batch compiler "ocamlc",
|
||||
which compiles Caml source files to bytecode object files and links
|
||||
which compiles OCaml source files to bytecode object files and links
|
||||
these object files to produce standalone bytecode executable files.
|
||||
These executable files are then run by the bytecode interpreter
|
||||
"ocamlrun".
|
||||
|
@ -27,7 +27,7 @@ Arguments ending in ".ml" are taken to be source files for compilation
|
|||
unit implementations. Implementations provide definitions for the
|
||||
names exported by the unit, and also contain expressions to be
|
||||
evaluated for their side-effects. From the file \var{x}".ml", the "ocamlc"
|
||||
compiler produces compiled object bytecode in the file \var{x}".cmo".
|
||||
compiler produces compiled object bytecode in the file \var{x}".cmo".
|
||||
|
||||
If the interface file \var{x}".mli" exists, the implementation
|
||||
\var{x}".ml" is checked against the corresponding compiled interface
|
||||
|
@ -74,7 +74,7 @@ C linker when linking in "-custom" mode (see the description of
|
|||
\item
|
||||
Arguments ending in ".so" (".dll" under Windows)
|
||||
are assumed to be C shared libraries (DLLs). During linking, they are
|
||||
searched for external C functions referenced from the Caml code,
|
||||
searched for external C functions referenced from the OCaml code,
|
||||
and their names are written in the generated bytecode executable.
|
||||
The run-time system "ocamlrun" then loads them dynamically at program
|
||||
start-up time.
|
||||
|
@ -83,19 +83,19 @@ start-up time.
|
|||
|
||||
The output of the linking phase is a file containing compiled bytecode
|
||||
that can be executed by the OCaml bytecode interpreter:
|
||||
the command named "ocamlrun". If "caml.out" is the name of the file
|
||||
the command named "ocamlrun". If "a.out" is the name of the file
|
||||
produced by the linking phase, the command
|
||||
\begin{alltt}
|
||||
ocamlrun caml.out \nth{arg}{1} \nth{arg}{2} \ldots \nth{arg}{n}
|
||||
ocamlrun a.out \nth{arg}{1} \nth{arg}{2} \ldots \nth{arg}{n}
|
||||
\end{alltt}
|
||||
executes the compiled code contained in "caml.out", passing it as
|
||||
executes the compiled code contained in "a.out", passing it as
|
||||
arguments the character strings \nth{arg}{1} to \nth{arg}{n}.
|
||||
(See chapter~\ref{c:runtime} for more details.)
|
||||
|
||||
On most systems, the file produced by the linking
|
||||
phase can be run directly, as in:
|
||||
\begin{alltt}
|
||||
./caml.out \nth{arg}{1} \nth{arg}{2} \ldots \nth{arg}{n}
|
||||
./a.out \nth{arg}{1} \nth{arg}{2} \ldots \nth{arg}{n}
|
||||
\end{alltt}
|
||||
The produced file has the executable bit set, and it manages to launch
|
||||
the bytecode interpreter by itself.
|
||||
|
@ -151,7 +151,7 @@ given C library to be linked with the program.
|
|||
Pass the given option to the C compiler and linker. When linking in
|
||||
``custom runtime'' mode, for instance,
|
||||
"-ccopt -L"\var{dir} causes the C linker to search for C libraries in
|
||||
directory \var{dir}. (See the "-custom" option.)
|
||||
directory \var{dir}. (See the "-custom" option.)
|
||||
|
||||
\item["-config"]
|
||||
Print the version number of "ocamlc" and a detailed summary of its
|
||||
|
@ -165,7 +165,7 @@ linker produces an output file that contains both the runtime system
|
|||
and the bytecode for the program. The resulting file is larger, but it
|
||||
can be executed directly, even if the "ocamlrun" command is not
|
||||
installed. Moreover, the ``custom runtime'' mode enables static
|
||||
linking of Caml code with user-defined C functions, as described in
|
||||
linking of OCaml code with user-defined C functions, as described in
|
||||
chapter~\ref{c:intf-c}.
|
||||
\begin{unix}
|
||||
Never use the "strip" command on executables produced by "ocamlc -custom",
|
||||
|
@ -276,7 +276,7 @@ source file that appears on the command line.
|
|||
|
||||
\item["-output-obj"]
|
||||
Cause the linker to produce a C object file instead of a bytecode
|
||||
executable file. This is useful to wrap Caml code as a C library,
|
||||
executable file. This is useful to wrap OCaml code as a C library,
|
||||
callable from any C program. See chapter~\ref{c:intf-c},
|
||||
section~\ref{s:embedded-code}. The name of the output object file
|
||||
must be set with the "-o" option. This
|
||||
|
@ -342,7 +342,7 @@ accesses an array or string outside of its bounds.
|
|||
\item["-use-runtime" \var{runtime-name}]
|
||||
Generate a bytecode executable file that can be executed on the custom
|
||||
runtime system \var{runtime-name}, built earlier with
|
||||
"ocamlc -make-runtime" \var{runtime-name}.
|
||||
"ocamlc -make-runtime" \var{runtime-name}.
|
||||
See section~\ref{s:custom-runtime} for more information.
|
||||
|
||||
\item["-v"]
|
||||
|
@ -495,7 +495,7 @@ compiled interface file (".cmi" file), or a compiled bytecode file
|
|||
means you are trying to compile a file that references identifiers
|
||||
from module \var{mod}, but you have not yet compiled an interface for
|
||||
module \var{mod}. Fix: compile \var{mod}".mli" or \var{mod}".ml"
|
||||
first, to create the compiled interface \var{mod}".cmi".
|
||||
first, to create the compiled interface \var{mod}".cmi".
|
||||
|
||||
If \var{filename} has the format \var{mod}".cmo", this
|
||||
means you are trying to link a bytecode object file that does not
|
||||
|
@ -537,7 +537,7 @@ constructor is redefined. Example:
|
|||
f C
|
||||
\end{verbatim}
|
||||
This result in the error message ``expression "C" of type "foo" cannot
|
||||
be used with type "foo"''.
|
||||
be used with type "foo"''.
|
||||
|
||||
\item[The type of this expression, \var{t}, contains type variables
|
||||
that cannot be generalized]
|
||||
|
|
|
@ -482,17 +482,17 @@ command-line option.
|
|||
|
||||
\begin{options}
|
||||
\item["cd" \var{directory}]
|
||||
Set the working directory for "camldebug" to \var{directory}.
|
||||
Set the working directory for "ocamldebug" to \var{directory}.
|
||||
|
||||
\item["pwd"]
|
||||
Print the working directory for "camldebug".
|
||||
Print the working directory for "ocamldebug".
|
||||
\end{options}
|
||||
|
||||
\subsection{Turning reverse execution on and off}
|
||||
|
||||
In some cases, you may want to turn reverse execution off. This speeds
|
||||
up the program execution, and is also sometimes useful for interactive
|
||||
programs.
|
||||
programs.
|
||||
|
||||
Normally, the debugger takes checkpoints of the program state from
|
||||
time to time. That is, it makes a copy of the current state of the
|
||||
|
@ -613,9 +613,9 @@ Read debugger commands from the script \var{filename}.
|
|||
|
||||
The most user-friendly way to use the debugger is to run it under Emacs.
|
||||
See the file "emacs/README" in the distribution for information on how
|
||||
to load the Emacs Lisp files for Caml support.
|
||||
to load the Emacs Lisp files for OCaml support.
|
||||
|
||||
The Caml debugger is started under Emacs by the command "M-x
|
||||
The OCaml debugger is started under Emacs by the command "M-x
|
||||
camldebug", with argument the name of the executable file
|
||||
\var{progname} to debug. Communication with the debugger takes place
|
||||
in an Emacs buffer named "*camldebug-"\var{progname}"*". The editing
|
||||
|
@ -654,7 +654,7 @@ current frame.
|
|||
current frame.
|
||||
\end{options}
|
||||
|
||||
In all buffers in Caml editing mode, the following debugger commands
|
||||
In all buffers in OCaml editing mode, the following debugger commands
|
||||
are also available:
|
||||
|
||||
\begin{options}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
\pdfchapterfold{-9}{Interfacing C with OCaml}
|
||||
|
||||
This chapter describes how user-defined primitives, written in C, can
|
||||
be linked with Caml code and called from Caml functions.
|
||||
be linked with OCaml code and called from OCaml functions.
|
||||
|
||||
\section{Overview and compilation information}
|
||||
\pdfsection{Overview and compilation information}
|
||||
|
@ -36,10 +36,10 @@ thus hiding their implementation as a C function, or explicitly as
|
|||
\end{alltt}
|
||||
The latter is slightly more efficient, as it allows clients of the
|
||||
module to call directly the C function instead of going through the
|
||||
corresponding Caml function.
|
||||
corresponding OCaml function.
|
||||
|
||||
The arity (number of arguments) of a primitive is automatically
|
||||
determined from its Caml type in the "external" declaration, by
|
||||
determined from its OCaml type in the "external" declaration, by
|
||||
counting the number of function arrows in the type. For instance,
|
||||
"input" above has arity 4, and the "input" C function is called with
|
||||
four arguments. Similarly,
|
||||
|
@ -47,7 +47,7 @@ four arguments. Similarly,
|
|||
external input2 : in_channel * string * int * int -> int = "input2"
|
||||
\end{verbatim}
|
||||
has arity 1, and the "input2" C function receives one argument (which
|
||||
is a quadruple of Caml values).
|
||||
is a quadruple of OCaml values).
|
||||
|
||||
Type abbreviations are not expanded when determining the arity of a
|
||||
primitive. For instance,
|
||||
|
@ -64,9 +64,9 @@ to name the functional return type in a type abbreviation.
|
|||
|
||||
User primitives with arity $n \leq 5$ are implemented by C functions
|
||||
that take $n$ arguments of type "value", and return a result of type
|
||||
"value". The type "value" is the type of the representations for Caml
|
||||
"value". The type "value" is the type of the representations for OCaml
|
||||
values. It encodes objects of several base types (integers,
|
||||
floating-point numbers, strings, \ldots), as well as Caml data
|
||||
floating-point numbers, strings, \ldots), as well as OCaml data
|
||||
structures. The type "value" and the associated conversion
|
||||
functions and macros are described in details below. For instance,
|
||||
here is the declaration for the C function implementing the "input"
|
||||
|
@ -77,16 +77,16 @@ CAMLprim value input(value channel, value buffer, value offset, value length)
|
|||
...
|
||||
}
|
||||
\end{verbatim}
|
||||
When the primitive function is applied in a Caml program, the C
|
||||
When the primitive function is applied in an OCaml program, the C
|
||||
function is called with the values of the expressions to which the
|
||||
primitive is applied as arguments. The value returned by the function is
|
||||
passed back to the Caml program as the result of the function
|
||||
passed back to the OCaml program as the result of the function
|
||||
application.
|
||||
|
||||
User primitives with arity greater than 5 should be implemented by two
|
||||
C functions. The first function, to be used in conjunction with the
|
||||
bytecode compiler "ocamlc", receives two arguments: a pointer to an
|
||||
array of Caml values (the values for the arguments), and an
|
||||
array of OCaml values (the values for the arguments), and an
|
||||
integer which is the number of arguments provided. The other function,
|
||||
to be used in conjunction with the native-code compiler "ocamlopt",
|
||||
takes its arguments directly. For instance, here are the two C
|
||||
|
@ -118,15 +118,15 @@ For instance, in the case of "add_nat", the declaration is:
|
|||
|
||||
Implementing a user primitive is actually two separate tasks: on the
|
||||
one hand, decoding the arguments to extract C values from the given
|
||||
Caml values, and encoding the return value as a Caml
|
||||
OCaml values, and encoding the return value as an OCaml
|
||||
value; on the other hand, actually computing the result from the arguments.
|
||||
Except for very simple primitives, it is often preferable to have two
|
||||
distinct C functions to implement these two tasks. The first function
|
||||
actually implements the primitive, taking native C values as
|
||||
arguments and returning a native C value. The second function,
|
||||
often called the ``stub code'', is a simple wrapper around the first
|
||||
function that converts its arguments from Caml values to C values,
|
||||
call the first function, and convert the returned C value to Caml
|
||||
function that converts its arguments from OCaml values to C values,
|
||||
call the first function, and convert the returned C value to OCaml
|
||||
value. For instance, here is the stub code for the "input"
|
||||
primitive:
|
||||
\begin{verbatim}
|
||||
|
@ -140,7 +140,7 @@ CAMLprim value input(value channel, value buffer, value offset, value length)
|
|||
(Here, "Val_long", "Long_val" and so on are conversion macros for the
|
||||
type "value", that will be described later. The "CAMLprim" macro
|
||||
expands to the required compiler directives to ensure that the
|
||||
function following it is exported and accessible from Caml.)
|
||||
function following it is exported and accessible from OCaml.)
|
||||
The hard work is performed by the function "getblock", which is
|
||||
declared as:
|
||||
\begin{verbatim}
|
||||
|
@ -154,13 +154,13 @@ To write C code that operates on OCaml values, the following
|
|||
include files are provided:
|
||||
\begin{tableau}{|l|p{12cm}|}{Include file}{Provides}
|
||||
\entree{"caml/mlvalues.h"}{definition of the "value" type, and conversion macros}
|
||||
\entree{"caml/alloc.h"}{allocation functions (to create structured Caml
|
||||
\entree{"caml/alloc.h"}{allocation functions (to create structured OCaml
|
||||
objects)}
|
||||
\entree{"caml/memory.h"}{miscellaneous memory-related functions
|
||||
and macros (for GC interface, in-place modification of structures, etc).}
|
||||
\entree{"caml/fail.h"}{functions for raising exceptions
|
||||
(see section~\ref{s:c-exceptions})}
|
||||
\entree{"caml/callback.h"}{callback from C to Caml (see
|
||||
\entree{"caml/callback.h"}{callback from C to OCaml (see
|
||||
section~\ref{s:callback}).}
|
||||
\entree{"caml/custom.h"}{operations on custom blocks (see
|
||||
section~\ref{s:custom}).}
|
||||
|
@ -173,7 +173,7 @@ serialization and deserialization functions for custom blocks
|
|||
These files reside in the "caml/" subdirectory of the OCaml
|
||||
standard library directory (usually "/usr/local/lib/ocaml").
|
||||
|
||||
\subsection{Statically linking C code with Caml code}
|
||||
\subsection{Statically linking C code with OCaml code}
|
||||
\label{staticlink-c-code}
|
||||
|
||||
The OCaml runtime system comprises three main parts: the bytecode
|
||||
|
@ -182,13 +182,13 @@ implement the primitive operations. Some bytecode instructions are
|
|||
provided to call these C functions, designated by their offset in a
|
||||
table of functions (the table of primitives).
|
||||
|
||||
In the default mode, the Caml linker produces bytecode for the
|
||||
In the default mode, the OCaml linker produces bytecode for the
|
||||
standard runtime system, with a standard set of primitives. References
|
||||
to primitives that are not in this standard set result in the
|
||||
``unavailable C primitive'' error. (Unless dynamic loading of C
|
||||
libraries is supported -- see section~\ref{dynlink-c-code} below.)
|
||||
|
||||
In the ``custom runtime'' mode, the Caml linker scans the
|
||||
In the ``custom runtime'' mode, the OCaml linker scans the
|
||||
object files and determines the set of required primitives. Then, it
|
||||
builds a suitable runtime system, by calling the native code linker with:
|
||||
\begin{itemize}
|
||||
|
@ -196,10 +196,10 @@ builds a suitable runtime system, by calling the native code linker with:
|
|||
\item a library that provides the bytecode interpreter, the
|
||||
memory manager, and the standard primitives;
|
||||
\item libraries and object code files (".o" files) mentioned on the
|
||||
command line for the Caml linker, that provide implementations
|
||||
command line for the OCaml linker, that provide implementations
|
||||
for the user's primitives.
|
||||
\end{itemize}
|
||||
This builds a runtime system with the required primitives. The Caml
|
||||
This builds a runtime system with the required primitives. The OCaml
|
||||
linker generates bytecode for this custom runtime system. The
|
||||
bytecode is appended to the end of the custom runtime system, so that
|
||||
it will be automatically executed when the output file (custom
|
||||
|
@ -208,7 +208,7 @@ runtime + bytecode) is launched.
|
|||
To link in ``custom runtime'' mode, execute the "ocamlc" command with:
|
||||
\begin{itemize}
|
||||
\item the "-custom" option;
|
||||
\item the names of the desired Caml object files (".cmo" and ".cma" files) ;
|
||||
\item the names of the desired OCaml object files (".cmo" and ".cma" files) ;
|
||||
\item the names of the C object files and libraries (".o" and ".a"
|
||||
files) that implement the required primitives. Under Unix and Windows,
|
||||
a library named "lib"\var{name}".a" (respectively, ".lib") residing in one of the standard library directories can also be specified as "-cclib -l"\var{name}.
|
||||
|
@ -216,19 +216,19 @@ a library named "lib"\var{name}".a" (respectively, ".lib") residing in one of th
|
|||
|
||||
If you are using the native-code compiler "ocamlopt", the "-custom"
|
||||
flag is not needed, as the final linking phase of "ocamlopt" always
|
||||
builds a standalone executable. To build a mixed Caml/C executable,
|
||||
builds a standalone executable. To build a mixed OCaml/C executable,
|
||||
execute the "ocamlopt" command with:
|
||||
\begin{itemize}
|
||||
\item the names of the desired Caml native object files (".cmx" and
|
||||
\item the names of the desired OCaml native object files (".cmx" and
|
||||
".cmxa" files);
|
||||
\item the names of the C object files and libraries (".o", ".a",
|
||||
".so" or ".dll" files) that implement the required primitives.
|
||||
\end{itemize}
|
||||
|
||||
Starting with Objective Caml 3.00, it is possible to record the
|
||||
"-custom" option as well as the names of C libraries in a Caml
|
||||
library file ".cma" or ".cmxa". For instance, consider a Caml library
|
||||
"mylib.cma", built from the Caml object files "a.cmo" and "b.cmo",
|
||||
"-custom" option as well as the names of C libraries in an OCaml
|
||||
library file ".cma" or ".cmxa". For instance, consider an OCaml library
|
||||
"mylib.cma", built from the OCaml object files "a.cmo" and "b.cmo",
|
||||
which reference C code in "libmylib.a". If the library is
|
||||
built as follows:
|
||||
\begin{alltt}
|
||||
|
@ -256,14 +256,14 @@ options themselves at link-time:
|
|||
The former alternative is more convenient for the final users of the
|
||||
library, however.
|
||||
|
||||
\subsection{Dynamically linking C code with Caml code}
|
||||
\subsection{Dynamically linking C code with OCaml code}
|
||||
\label{dynlink-c-code}
|
||||
|
||||
Starting with Objective Caml 3.03, an alternative to static linking of C code
|
||||
using the "-custom" code is provided. In this mode, the Caml linker
|
||||
using the "-custom" code is provided. In this mode, the OCaml linker
|
||||
generates a pure bytecode executable (no embedded custom runtime
|
||||
system) that simply records the names of dynamically-loaded libraries
|
||||
containing the C code. The standard Caml runtime system "ocamlrun"
|
||||
containing the C code. The standard OCaml runtime system "ocamlrun"
|
||||
then loads dynamically these libraries, and resolves references to the
|
||||
required primitives, before executing the bytecode.
|
||||
|
||||
|
@ -272,7 +272,7 @@ Linux, MacOS~X, and Windows. It is supported, but not
|
|||
fully tested yet, under FreeBSD, Tru64, Solaris and Irix. It is not
|
||||
supported yet under other Unixes.
|
||||
|
||||
To dynamically link C code with Caml code, the C code must first be
|
||||
To dynamically link C code with OCaml code, the C code must first be
|
||||
compiled into a shared library (under Unix) or DLL (under Windows).
|
||||
This involves 1- compiling the C files with appropriate C compiler
|
||||
flags for producing position-independent code (when required by the
|
||||
|
@ -283,9 +283,9 @@ find it later at program start-up time (see
|
|||
section~\ref{s-ocamlrun-dllpath}).
|
||||
Finally (step 3), execute the "ocamlc" command with
|
||||
\begin{itemize}
|
||||
\item the names of the desired Caml object files (".cmo" and ".cma" files) ;
|
||||
\item the names of the desired OCaml object files (".cmo" and ".cma" files) ;
|
||||
\item the names of the C shared libraries (".so" or ".dll" files) that
|
||||
implement the required primitives. Under Unix and Windows,
|
||||
implement the required primitives. Under Unix and Windows,
|
||||
a library named "dll"\var{name}".so" (respectively, ".dll") residing
|
||||
in one of the standard library directories can also be specified as
|
||||
"-dllib -l"\var{name}.
|
||||
|
@ -296,9 +296,9 @@ The "ocamlmklib" tool (see section~\ref{s-ocamlmklib})
|
|||
automates steps 2 and 3.
|
||||
|
||||
As in the case of static linking, it is possible (and recommended) to
|
||||
record the names of C libraries in a Caml ".cma" library archive.
|
||||
Consider again a Caml library
|
||||
"mylib.cma", built from the Caml object files "a.cmo" and "b.cmo",
|
||||
record the names of C libraries in an OCaml ".cma" library archive.
|
||||
Consider again an OCaml library
|
||||
"mylib.cma", built from the OCaml object files "a.cmo" and "b.cmo",
|
||||
which reference C code in "dllmylib.so". If the library is
|
||||
built as follows:
|
||||
\begin{alltt}
|
||||
|
@ -319,9 +319,9 @@ statically linked (using "-custom") or dynamically linked.
|
|||
|
||||
\subsection{Choosing between static linking and dynamic linking}
|
||||
|
||||
After having described two different ways of linking C code with Caml
|
||||
After having described two different ways of linking C code with OCaml
|
||||
code, we now review the pros and cons of each, to help developers of
|
||||
mixed Caml/C libraries decide.
|
||||
mixed OCaml/C libraries decide.
|
||||
|
||||
The main advantage of dynamic linking is that it preserves the
|
||||
platform-independence of bytecode executables. That is, the bytecode
|
||||
|
@ -335,7 +335,7 @@ addition, dynamic linking results in smaller executables.
|
|||
|
||||
Another advantage of dynamic linking is that the final users of the
|
||||
library do not need to have a C compiler, C linker, and C runtime
|
||||
libraries installed on their machines. This is no big deal under
|
||||
libraries installed on their machines. This is no big deal under
|
||||
Unix and Cygwin, but many Windows users are reluctant to install
|
||||
Microsoft Visual C just to be able to do "ocamlc -custom".
|
||||
|
||||
|
@ -370,7 +370,7 @@ portable way.
|
|||
\label{s:custom-runtime}
|
||||
|
||||
It is sometimes inconvenient to build a custom runtime system each
|
||||
time Caml code is linked with C libraries, like "ocamlc -custom" does.
|
||||
time OCaml code is linked with C libraries, like "ocamlc -custom" does.
|
||||
For one thing, the building of the runtime system is slow on some
|
||||
systems (that have bad linkers or slow remote file systems); for
|
||||
another thing, the platform-independence of bytecode files is lost,
|
||||
|
@ -404,7 +404,7 @@ bytecode executable (so that the bytecode from "unix.cma" and
|
|||
\section{The "value" type}
|
||||
\pdfsection{The value type}
|
||||
|
||||
All Caml objects are represented by the C type "value",
|
||||
All OCaml objects are represented by the C type "value",
|
||||
defined in the include file "caml/mlvalues.h", along with macros to
|
||||
manipulate values of that type. An object of type "value" is either:
|
||||
\begin{itemize}
|
||||
|
@ -435,7 +435,7 @@ structured input-output, structured and raw blocks are further
|
|||
classified according to their tags as follows:
|
||||
\begin{tableau}{|l|p{10cm}|}{Tag}{Contents of the block}
|
||||
\entree{0 to $\hbox{"No_scan_tag"}-1$}{A structured block (an array of
|
||||
Caml objects). Each field is a "value".}
|
||||
OCaml objects). Each field is a "value".}
|
||||
\entree{"Closure_tag"}{A closure representing a functional value. The first
|
||||
word is a pointer to a piece of code, the remaining words are
|
||||
"value" containing the environment.}
|
||||
|
@ -457,24 +457,24 @@ cast to and from the type "value". This includes pointers returned by
|
|||
obtained with the \verb'&' operator.
|
||||
|
||||
Caution: if a pointer returned by "malloc" is cast to the type "value"
|
||||
and returned to Caml, explicit deallocation of the pointer using
|
||||
and returned to OCaml, explicit deallocation of the pointer using
|
||||
"free" is potentially dangerous, because the pointer may still be
|
||||
accessible from the Caml world. Worse, the memory space deallocated
|
||||
by "free" can later be reallocated as part of the Caml heap; the
|
||||
pointer, formerly pointing outside the Caml heap, now points inside
|
||||
the Caml heap, and this can confuse the garbage collector. To avoid
|
||||
these problems, it is preferable to wrap the pointer in a Caml block
|
||||
accessible from the OCaml world. Worse, the memory space deallocated
|
||||
by "free" can later be reallocated as part of the OCaml heap; the
|
||||
pointer, formerly pointing outside the OCaml heap, now points inside
|
||||
the OCaml heap, and this can confuse the garbage collector. To avoid
|
||||
these problems, it is preferable to wrap the pointer in a OCaml block
|
||||
with tag "Abstract_tag" or "Custom_tag".
|
||||
|
||||
\section{Representation of Caml data types}
|
||||
\pdfsection{Representation of Caml data types}
|
||||
\section{Representation of OCaml data types}
|
||||
\pdfsection{Representation of OCaml data types}
|
||||
|
||||
This section describes how Caml data types are encoded in the
|
||||
This section describes how OCaml data types are encoded in the
|
||||
"value" type.
|
||||
|
||||
\subsection{Atomic types}
|
||||
|
||||
\begin{tableau}{|l|l|}{Caml type}{Encoding}
|
||||
\begin{tableau}{|l|l|}{OCaml type}{Encoding}
|
||||
\entree{"int"}{Unboxed integer values.}
|
||||
\entree{"char"}{Unboxed integer values (ASCII code).}
|
||||
\entree{"float"}{Blocks with tag "Double_tag".}
|
||||
|
@ -500,7 +500,7 @@ are represented as arrays of floating-point numbers, with tag
|
|||
|
||||
\subsection{Arrays}
|
||||
|
||||
Arrays of integers and pointers are represented like tuples,
|
||||
Arrays of integers and pointers are represented like tuples,
|
||||
that is, as pointers to blocks tagged~0. They are accessed with the
|
||||
"Field" macro for reading and the "caml_modify" function for writing.
|
||||
|
||||
|
@ -575,7 +575,7 @@ Like constructed terms, polymorphic variant values are represented either
|
|||
as integers (for polymorphic variants without arguments), or as blocks
|
||||
(for polymorphic variants with an argument). Unlike constructed
|
||||
terms, variant constructors are not numbered starting from 0, but
|
||||
identified by a hash value (a Caml integer), as computed by the C function
|
||||
identified by a hash value (an OCaml integer), as computed by the C function
|
||||
"hash_variant" (declared in "<caml/mlvalues.h>"):
|
||||
the hash value for a variant constructor named, say, "VConstr"
|
||||
is "hash_variant(\"VConstr\")".
|
||||
|
@ -612,11 +612,11 @@ and false if it is an immediate integer.
|
|||
\item "Long_val("\var{v}")" returns the "long int" encoded in value \var{v}.
|
||||
\item "Val_int("\var{i}")" returns the value encoding the "int" \var{i}.
|
||||
\item "Int_val("\var{v}")" returns the "int" encoded in value \var{v}.
|
||||
\item "Val_bool("\var{x}")" returns the Caml boolean representing the
|
||||
\item "Val_bool("\var{x}")" returns the OCaml boolean representing the
|
||||
truth value of the C integer \var{x}.
|
||||
\item "Bool_val("\var{v}")" returns 0 if \var{v} is the Caml boolean
|
||||
\item "Bool_val("\var{v}")" returns 0 if \var{v} is the OCaml boolean
|
||||
"false", 1 if \var{v} is "true".
|
||||
\item "Val_true", "Val_false" represent the Caml booleans "true" and "false".
|
||||
\item "Val_true", "Val_false" represent the OCaml booleans "true" and "false".
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Accessing blocks}
|
||||
|
@ -642,9 +642,9 @@ $\hbox{"string_length"}(v)-1$.
|
|||
$\hbox{"string_length"}(v)-1$.
|
||||
\item "String_val("\var{v}")" returns a pointer to the first byte of the string
|
||||
\var{v}, with type "char *". This pointer is a valid C string: there is a
|
||||
null character after the last character in the string. However, Caml
|
||||
null character after the last character in the string. However, OCaml
|
||||
strings can contain embedded null characters, that will confuse
|
||||
the usual C functions over strings.
|
||||
the usual C functions over strings.
|
||||
\item "Double_val("\var{v}")" returns the floating-point number contained in
|
||||
value \var{v}, with type "double".
|
||||
\item "Double_field("\var{v}", "\var{n}")" returns
|
||||
|
@ -701,7 +701,7 @@ the null-terminated C string \var{s} (a "char *").
|
|||
with the "double" \var{d}.
|
||||
\item
|
||||
"caml_copy_int32("\var{i}")", "copy_int64("\var{i}")" and
|
||||
"caml_copy_nativeint("\var{i}")" return a value of Caml type "int32",
|
||||
"caml_copy_nativeint("\var{i}")" return a value of OCaml type "int32",
|
||||
"int64" and "nativeint", respectively, initialized with the integer
|
||||
\var{i}.
|
||||
\item
|
||||
|
@ -737,18 +737,18 @@ against \verb"Max_young_wosize" to determine the correct allocation procedure.
|
|||
\begin{itemize}
|
||||
\item
|
||||
"caml_alloc_small("\var{n}", "\var{t}")" returns a fresh small block of size
|
||||
$n \leq \hbox{"Max_young_wosize"}$ words, with tag \var{t}.
|
||||
If this block is a structured block (i.e. if $t < \hbox{"No_scan_tag"}$), then
|
||||
$n \leq \hbox{"Max_young_wosize"}$ words, with tag \var{t}.
|
||||
If this block is a structured block (i.e. if $t < \hbox{"No_scan_tag"}$), then
|
||||
the fields of the block (initially containing garbage) must be initialized
|
||||
with legal values (using direct assignment to the fields of the block)
|
||||
before the next allocation.
|
||||
\item
|
||||
"caml_alloc_shr("\var{n}", "\var{t}")" returns a fresh block of size
|
||||
\var{n}, with tag \var{t}.
|
||||
\var{n}, with tag \var{t}.
|
||||
The size of the block can be greater than \verb"Max_young_wosize". (It
|
||||
can also be smaller, but in this case it is more efficient to call
|
||||
"caml_alloc_small" instead of "caml_alloc_shr".)
|
||||
If this block is a structured block (i.e. if $t < \hbox{"No_scan_tag"}$), then
|
||||
"caml_alloc_small" instead of "caml_alloc_shr".)
|
||||
If this block is a structured block (i.e. if $t < \hbox{"No_scan_tag"}$), then
|
||||
the fields of the block (initially containing garbage) must be initialized
|
||||
with legal values (using the "caml_initialize" function described below)
|
||||
before the next allocation.
|
||||
|
@ -766,7 +766,7 @@ with argument \var{s}.
|
|||
\end{itemize}
|
||||
|
||||
Raising arbitrary exceptions from C is more delicate: the
|
||||
exception identifier is dynamically allocated by the Caml program, and
|
||||
exception identifier is dynamically allocated by the OCaml program, and
|
||||
therefore must be communicated to the C function using the
|
||||
registration facility described below in section~\ref{s:register-exn}.
|
||||
Once the exception identifier is recovered in C, the following
|
||||
|
@ -775,9 +775,9 @@ functions actually raise the exception:
|
|||
\item "caml_raise_constant("\var{id}")" raises the exception \var{id} with
|
||||
no argument;
|
||||
\item "caml_raise_with_arg("\var{id}", "\var{v}")" raises the exception
|
||||
\var{id} with the Caml value \var{v} as argument;
|
||||
\var{id} with the OCaml value \var{v} as argument;
|
||||
\item "caml_raise_with_args("\var{id}", "\var{n}", "\var{v}")"
|
||||
raises the exception \var{id} with the Caml values
|
||||
raises the exception \var{id} with the OCaml values
|
||||
\var{v}"[0]", \ldots, \var{v}"["\var{n}"-1]" as arguments;
|
||||
\item "caml_raise_with_string("\var{id}", "\var{s}")", where \var{s} is a
|
||||
null-terminated C string, raises the exception \var{id} with a copy of
|
||||
|
@ -963,7 +963,7 @@ value (see rule~6).
|
|||
%% "Begin_roots" and "End_roots" macros), if they are to survive a call
|
||||
%% to an allocation function.
|
||||
%% \end{gcrule}
|
||||
%%
|
||||
%%
|
||||
%% Registration is performed with the "Begin_roots" set of macros.
|
||||
%% "Begin_roots1("\var{v}")" registers variable \var{v} with the garbage
|
||||
%% collector. Generally, \var{v} will be a local variable or a
|
||||
|
@ -975,20 +975,20 @@ value (see rule~6).
|
|||
%% allows you to register an array of roots. \var{ptr} is a pointer to
|
||||
%% the first element, and \var{size} is the number of elements in the
|
||||
%% array.
|
||||
%%
|
||||
%%
|
||||
%% Once registered, each of your variables (or array element) has the
|
||||
%% following properties: if it points to a heap-allocated block, this
|
||||
%% block (and its contents) will not be reclaimed; moreover, if this
|
||||
%% block is relocated by the garbage collector, the variable is updated
|
||||
%% to point to the new location for the block.
|
||||
%%
|
||||
%%
|
||||
%% Each of the "Begin_roots" macros open a C block that must be closed
|
||||
%% with a matching "End_roots" at the same nesting level. The block must
|
||||
%% be exited normally (i.e. not with "return" or "goto"). However, the
|
||||
%% roots are automatically un-registered if a Caml exception is raised,
|
||||
%% roots are automatically un-registered if an OCaml exception is raised,
|
||||
%% so you can exit the block with "failwith", "invalid_argument", or one
|
||||
%% of the "raise" functions.
|
||||
%%
|
||||
%%
|
||||
%% {\bf Note:} The "Begin_roots" macros use a local variable and a
|
||||
%% structure tag named "caml__roots_block". Do not use this identifier
|
||||
%% in your programs.
|
||||
|
@ -998,7 +998,7 @@ value (see rule~6).
|
|||
Field(\var{v}, \var{n}) = \var{w};
|
||||
\end{alltt}
|
||||
is safe only if \var{v} is a block newly allocated by "caml_alloc_small";
|
||||
that is, if no allocation took place between the
|
||||
that is, if no allocation took place between the
|
||||
allocation of \var{v} and the assignment to the field. In all other cases,
|
||||
never assign directly. If the block has just been allocated by "caml_alloc_shr",
|
||||
use "caml_initialize" to assign a value to a field for the first time:
|
||||
|
@ -1113,7 +1113,7 @@ The stub code file, "curses_stubs.c", looks like this:
|
|||
#include <caml/custom.h>
|
||||
|
||||
/* Encapsulation of opaque window handles (of type WINDOW *)
|
||||
as Caml custom blocks. */
|
||||
as OCaml custom blocks. */
|
||||
|
||||
static struct custom_operations curses_window_ops = {
|
||||
"fr.inria.caml.curses_windows",
|
||||
|
@ -1124,10 +1124,10 @@ static struct custom_operations curses_window_ops = {
|
|||
custom_deserialize_default
|
||||
};
|
||||
|
||||
/* Accessing the WINDOW * part of a Caml custom block */
|
||||
/* Accessing the WINDOW * part of an OCaml custom block */
|
||||
#define Window_val(v) (*((WINDOW **) Data_custom_val(v)))
|
||||
|
||||
/* Allocating a Caml custom block to hold the given WINDOW * */
|
||||
/* Allocating an OCaml custom block to hold the given WINDOW * */
|
||||
static value alloc_window(WINDOW * w)
|
||||
{
|
||||
value v = alloc_custom(&curses_window_ops, sizeof(WINDOW *), 0, 1);
|
||||
|
@ -1211,7 +1211,7 @@ or, even simpler,
|
|||
(When passed a ".c" file, the "ocamlc" command simply calls the C
|
||||
compiler on that file, with the right "-I" option.)
|
||||
|
||||
Now, here is a sample Caml program "test.ml" that uses the "curses"
|
||||
Now, here is a sample OCaml program "test.ml" that uses the "curses"
|
||||
module:
|
||||
\begin{verbatim}
|
||||
open Curses
|
||||
|
@ -1230,61 +1230,61 @@ To compile and link this program, run:
|
|||
(On some machines, you may need to put "-cclib -ltermcap" or
|
||||
"-cclib -lcurses -cclib -ltermcap" instead of "-cclib -lcurses".)
|
||||
|
||||
\section{Advanced topic: callbacks from C to Caml} \label{s:callback}
|
||||
\pdfsection{Advanced topic: callbacks from C to Caml}
|
||||
\section{Advanced topic: callbacks from C to OCaml} \label{s:callback}
|
||||
\pdfsection{Advanced topic: callbacks from C to OCaml}
|
||||
|
||||
So far, we have described how to call C functions from Caml. In this
|
||||
section, we show how C functions can call Caml functions, either as
|
||||
callbacks (Caml calls C which calls Caml), or because the main program
|
||||
So far, we have described how to call C functions from OCaml. In this
|
||||
section, we show how C functions can call OCaml functions, either as
|
||||
callbacks (OCaml calls C which calls OCaml), or because the main program
|
||||
is written in C.
|
||||
|
||||
\subsection{Applying Caml closures from C} \label{s:callbacks}
|
||||
\subsection{Applying OCaml closures from C} \label{s:callbacks}
|
||||
|
||||
C functions can apply Caml functional values (closures) to Caml values.
|
||||
C functions can apply OCaml functional values (closures) to OCaml values.
|
||||
The following functions are provided to perform the applications:
|
||||
\begin{itemize}
|
||||
\item "caml_callback("\var{f, a}")" applies the functional value \var{f} to
|
||||
the value \var{a} and return the value returned by~\var{f}.
|
||||
\item "caml_callback2("\var{f, a, b}")" applies the functional value \var{f}
|
||||
(which is assumed to be a curried Caml function with two arguments) to
|
||||
(which is assumed to be a curried OCaml function with two arguments) to
|
||||
\var{a} and \var{b}.
|
||||
\item "caml_callback3("\var{f, a, b, c}")" applies the functional value \var{f}
|
||||
(a curried Caml function with three arguments) to \var{a}, \var{b} and \var{c}.
|
||||
(a curried OCaml function with three arguments) to \var{a}, \var{b} and \var{c}.
|
||||
\item "caml_callbackN("\var{f, n, args}")" applies the functional value \var{f}
|
||||
to the \var{n} arguments contained in the array of values \var{args}.
|
||||
\end{itemize}
|
||||
If the function \var{f} does not return, but raises an exception that
|
||||
escapes the scope of the application, then this exception is
|
||||
propagated to the next enclosing Caml code, skipping over the C
|
||||
code. That is, if a Caml function \var{f} calls a C function \var{g} that
|
||||
calls back a Caml function \var{h} that raises a stray exception, then the
|
||||
propagated to the next enclosing OCaml code, skipping over the C
|
||||
code. That is, if an OCaml function \var{f} calls a C function \var{g} that
|
||||
calls back an OCaml function \var{h} that raises a stray exception, then the
|
||||
execution of \var{g} is interrupted and the exception is propagated back
|
||||
into \var{f}.
|
||||
|
||||
If the C code wishes to catch exceptions escaping the Caml function,
|
||||
If the C code wishes to catch exceptions escaping the OCaml function,
|
||||
it can use the functions "caml_callback_exn", "caml_callback2_exn",
|
||||
"caml_callback3_exn", "caml_callbackN_exn". These functions take the same
|
||||
arguments as their non-"_exn" counterparts, but catch escaping
|
||||
exceptions and return them to the C code. The return value \var{v} of the
|
||||
"caml_callback*_exn" functions must be tested with the macro
|
||||
"Is_exception_result("\var{v}")". If the macro returns ``false'', no
|
||||
exception occured, and \var{v} is the value returned by the Caml
|
||||
exception occured, and \var{v} is the value returned by the OCaml
|
||||
function. If "Is_exception_result("\var{v}")" returns ``true'',
|
||||
an exception escaped, and its value (the exception descriptor) can be
|
||||
recovered using "Extract_exception("\var{v}")".
|
||||
|
||||
\subsection{Registering Caml closures for use in C functions}
|
||||
\subsection{Registering OCaml closures for use in C functions}
|
||||
|
||||
The main difficulty with the "callback" functions described above is
|
||||
obtaining a closure to the Caml function to be called. For this
|
||||
obtaining a closure to the OCaml function to be called. For this
|
||||
purpose, OCaml provides a simple registration mechanism, by
|
||||
which Caml code can register Caml functions under some global name,
|
||||
which OCaml code can register OCaml functions under some global name,
|
||||
and then C code can retrieve the corresponding closure by this global
|
||||
name.
|
||||
|
||||
On the Caml side, registration is performed by evaluating
|
||||
On the OCaml side, registration is performed by evaluating
|
||||
"Callback.register" \var{n} \var{v}. Here, \var{n} is the global name
|
||||
(an arbitrary string) and \var{v} the Caml value. For instance:
|
||||
(an arbitrary string) and \var{v} the OCaml value. For instance:
|
||||
\begin{verbatim}
|
||||
let f x = print_string "f is applied to "; print_int x; print_newline()
|
||||
let _ = Callback.register "test function" f
|
||||
|
@ -1292,9 +1292,9 @@ On the Caml side, registration is performed by evaluating
|
|||
|
||||
On the C side, a pointer to the value registered under name \var{n} is
|
||||
obtained by calling "caml_named_value("\var{n}")". The returned
|
||||
pointer must then be dereferenced to recover the actual Caml value.
|
||||
pointer must then be dereferenced to recover the actual OCaml value.
|
||||
If no value is registered under the name \var{n}, the null pointer is
|
||||
returned. For example, here is a C wrapper that calls the Caml function "f"
|
||||
returned. For example, here is a C wrapper that calls the OCaml function "f"
|
||||
above:
|
||||
\begin{verbatim}
|
||||
void call_caml_f(int arg)
|
||||
|
@ -1321,10 +1321,10 @@ only once:
|
|||
}
|
||||
\end{verbatim}
|
||||
|
||||
\subsection{Registering Caml exceptions for use in C functions} \label{s:register-exn}
|
||||
\subsection{Registering OCaml exceptions for use in C functions} \label{s:register-exn}
|
||||
|
||||
The registration mechanism described above can also be used to
|
||||
communicate exception identifiers from Caml to C. The Caml code
|
||||
communicate exception identifiers from OCaml to C. The OCaml code
|
||||
registers the exception by evaluating
|
||||
"Callback.register_exception" \var{n} \var{exn}, where \var{n} is an
|
||||
arbitrary name and \var{exn} is an exception value of the
|
||||
|
@ -1348,44 +1348,44 @@ the given argument:
|
|||
|
||||
\subsection{Main program in C} \label{s:main-c}
|
||||
|
||||
In normal operation, a mixed Caml/C program starts by executing the
|
||||
Caml initialization code, which then may proceed to call C
|
||||
functions. We say that the main program is the Caml code. In some
|
||||
In normal operation, a mixed OCaml/C program starts by executing the
|
||||
OCaml initialization code, which then may proceed to call C
|
||||
functions. We say that the main program is the OCaml code. In some
|
||||
applications, it is desirable that the C code plays the role of the
|
||||
main program, calling Caml functions when needed. This can be achieved as
|
||||
main program, calling OCaml functions when needed. This can be achieved as
|
||||
follows:
|
||||
\begin{itemize}
|
||||
\item The C part of the program must provide a "main" function,
|
||||
which will override the default "main" function provided by the Caml
|
||||
which will override the default "main" function provided by the OCaml
|
||||
runtime system. Execution will start in the user-defined "main" function
|
||||
just like for a regular C program.
|
||||
|
||||
\item At some point, the C code must call "caml_main(argv)" to
|
||||
initialize the Caml code. The "argv" argument is a C array of strings
|
||||
initialize the OCaml code. The "argv" argument is a C array of strings
|
||||
(type "char **"), terminated with a "NULL" pointer,
|
||||
which represents the command-line arguments, as
|
||||
passed as second argument to "main". The Caml array "Sys.argv" will
|
||||
passed as second argument to "main". The OCaml array "Sys.argv" will
|
||||
be initialized from this parameter. For the bytecode compiler,
|
||||
"argv[0]" and "argv[1]" are also consulted to find the file containing
|
||||
the bytecode.
|
||||
|
||||
\item The call to "caml_main" initializes the Caml runtime system,
|
||||
\item The call to "caml_main" initializes the OCaml runtime system,
|
||||
loads the bytecode (in the case of the bytecode compiler), and
|
||||
executes the initialization code of the Caml program. Typically, this
|
||||
executes the initialization code of the OCaml program. Typically, this
|
||||
initialization code registers callback functions using "Callback.register".
|
||||
Once the Caml initialization code is complete, control returns to the
|
||||
Once the OCaml initialization code is complete, control returns to the
|
||||
C code that called "caml_main".
|
||||
|
||||
\item The C code can then invoke Caml functions using the callback
|
||||
\item The C code can then invoke OCaml functions using the callback
|
||||
mechanism (see section~\ref{s:callbacks}).
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Embedding the Caml code in the C code} \label{s:embedded-code}
|
||||
\subsection{Embedding the OCaml code in the C code} \label{s:embedded-code}
|
||||
|
||||
The bytecode compiler in custom runtime mode ("ocamlc -custom")
|
||||
normally appends the bytecode to the executable file containing the
|
||||
custom runtime. This has two consequences. First, the final linking
|
||||
step must be performed by "ocamlc". Second, the Caml runtime library
|
||||
step must be performed by "ocamlc". Second, the OCaml runtime library
|
||||
must be able to find the name of the executable file from the
|
||||
command-line arguments. When using "caml_main(argv)" as in
|
||||
section~\ref{s:main-c}, this means that "argv[0]" or "argv[1]" must
|
||||
|
@ -1394,13 +1394,13 @@ contain the executable file name.
|
|||
An alternative is to embed the bytecode in the C code. The
|
||||
"-output-obj" option to "ocamlc" is provided for this purpose. It
|
||||
causes the "ocamlc" compiler to output a C object file (".o" file,
|
||||
".obj" under Windows) containing the bytecode for the Caml part of the
|
||||
".obj" under Windows) containing the bytecode for the OCaml part of the
|
||||
program, as well as a "caml_startup" function. The C object file
|
||||
produced by "ocamlc -output-obj" can then be linked with C code using
|
||||
the standard C compiler, or stored in a C library.
|
||||
|
||||
The "caml_startup" function must be called from the main C program in
|
||||
order to initialize the Caml runtime and execute the Caml
|
||||
order to initialize the OCaml runtime and execute the OCaml
|
||||
initialization code. Just like "caml_main", it takes one "argv"
|
||||
parameter containing the command-line parameters. Unlike "caml_main",
|
||||
this "argv" parameter is used only to initialize "Sys.argv", but not
|
||||
|
@ -1408,26 +1408,26 @@ for finding the name of the executable file.
|
|||
|
||||
The "-output-obj" option can also be used to obtain the C source file.
|
||||
More interestingly, the same option can also produce directly a shared
|
||||
library (".so" file, ".dll" under Windows) that contains the Caml
|
||||
code, the Caml runtime system and any other static C code given to
|
||||
library (".so" file, ".dll" under Windows) that contains the OCaml
|
||||
code, the OCaml runtime system and any other static C code given to
|
||||
"ocamlc" (".o", ".a", respectively, ".obj", ".lib"). This use of
|
||||
"-output-obj" is very similar to a normal linking step, but instead of
|
||||
producing a main program that automatically runs the Caml code, it
|
||||
produces a shared library that can run the Caml code on demand. The
|
||||
producing a main program that automatically runs the OCaml code, it
|
||||
produces a shared library that can run the OCaml code on demand. The
|
||||
three possible behaviors of "-output-obj" are selected according
|
||||
to the extension of the resulting file (given with "-o").
|
||||
|
||||
The native-code compiler "ocamlopt" also supports the "-output-obj"
|
||||
option, causing it to output a C object file or a shared library
|
||||
containing the native code for all Caml modules on the command-line,
|
||||
as well as the Caml startup code. Initialization is performed by
|
||||
containing the native code for all OCaml modules on the command-line,
|
||||
as well as the OCaml startup code. Initialization is performed by
|
||||
calling "caml_startup" as in the case of the bytecode compiler.
|
||||
|
||||
For the final linking phase, in addition to the object file produced
|
||||
by "-output-obj", you will have to provide the OCaml runtime
|
||||
library ("libcamlrun.a" for bytecode, "libasmrun.a" for native-code),
|
||||
as well as all C libraries that are required by the Caml libraries
|
||||
used. For instance, assume the Caml part of your program uses the
|
||||
as well as all C libraries that are required by the OCaml libraries
|
||||
used. For instance, assume the OCaml part of your program uses the
|
||||
Unix library. With "ocamlc", you should do:
|
||||
\begin{alltt}
|
||||
ocamlc -output-obj -o camlcode.o unix.cma {\it{other}} .cmo {\it{and}} .cma {\it{files}}
|
||||
|
@ -1456,7 +1456,7 @@ compilation of OCaml, as the variables "BYTECCLINKOPTS"
|
|||
attention are:
|
||||
\begin{itemize}
|
||||
\item Windows with the MSVC compiler: the object file produced by
|
||||
Objective Caml have been compiled with the "/MD" flag, and therefore
|
||||
OCaml have been compiled with the "/MD" flag, and therefore
|
||||
all other object files linked with it should also be compiled with
|
||||
"/MD".
|
||||
\end{itemize}
|
||||
|
@ -1469,20 +1469,20 @@ by "ocamlopt -g" is embedded in a C program: stack backtrace
|
|||
information is available, but the backtrace mechanism needs to be
|
||||
turned on programmatically. This can be achieved from the OCaml side
|
||||
by calling "Printexc.record_backtrace true" in the initialization of
|
||||
one of the Caml modules. This can also be achieved from the C side
|
||||
by calling "caml_record_backtrace(Val_int(1));" in the Caml-C glue code.
|
||||
one of the OCaml modules. This can also be achieved from the C side
|
||||
by calling "caml_record_backtrace(Val_int(1));" in the OCaml-C glue code.
|
||||
|
||||
\section{Advanced example with callbacks}
|
||||
\pdfsection{Advanced example with callbacks}
|
||||
|
||||
This section illustrates the callback facilities described in
|
||||
section~\ref{s:callback}. We are going to package some Caml functions
|
||||
section~\ref{s:callback}. We are going to package some OCaml functions
|
||||
in such a way that they can be linked with C code and called from C
|
||||
just like any C functions. The Caml functions are defined in the
|
||||
following "mod.ml" Caml source:
|
||||
just like any C functions. The OCaml functions are defined in the
|
||||
following "mod.ml" OCaml source:
|
||||
|
||||
\begin{verbatim}
|
||||
(* File mod.ml -- some ``useful'' Caml functions *)
|
||||
(* File mod.ml -- some ``useful'' OCaml functions *)
|
||||
|
||||
let rec fib n = if n < 2 then 1 else fib(n-1) + fib(n-2)
|
||||
|
||||
|
@ -1497,7 +1497,7 @@ let _ = Callback.register "format_result" format_result
|
|||
Here is the C stub code for calling these functions from C:
|
||||
|
||||
\begin{verbatim}
|
||||
/* File modwrap.c -- wrappers around the Caml functions */
|
||||
/* File modwrap.c -- wrappers around the OCaml functions */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -1522,8 +1522,8 @@ char * format_result(int n)
|
|||
}
|
||||
\end{verbatim}
|
||||
|
||||
We now compile the Caml code to a C object file and put it in a C
|
||||
library along with the stub code in "modwrap.c" and the Caml runtime system:
|
||||
We now compile the OCaml code to a C object file and put it in a C
|
||||
library along with the stub code in "modwrap.c" and the OCaml runtime system:
|
||||
\begin{verbatim}
|
||||
ocamlc -custom -output-obj -o modcaml.o mod.ml
|
||||
ocamlc -c modwrap.c
|
||||
|
@ -1539,7 +1539,7 @@ program, just like regular C functions. Just remember to call
|
|||
"caml_startup" once before.
|
||||
|
||||
\begin{verbatim}
|
||||
/* File main.c -- a sample client for the Caml functions */
|
||||
/* File main.c -- a sample client for the OCaml functions */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -1547,7 +1547,7 @@ int main(int argc, char ** argv)
|
|||
{
|
||||
int result;
|
||||
|
||||
/* Initialize Caml code */
|
||||
/* Initialize OCaml code */
|
||||
caml_startup(argv);
|
||||
/* Do some computation */
|
||||
result = fib(10);
|
||||
|
@ -1589,7 +1589,7 @@ finalization function is associated with the block.
|
|||
|
||||
\item "int (*compare)(value v1, value v2)" \\
|
||||
The "compare" field contains a pointer to a C function that is
|
||||
called whenever two custom blocks are compared using Caml's generic
|
||||
called whenever two custom blocks are compared using OCaml's generic
|
||||
comparison operators ("=", "<>", "<=", ">=", "<", ">" and
|
||||
"compare"). The C function should return 0 if the data contained in
|
||||
the two blocks are structurally equal, a negative integer if the data
|
||||
|
@ -1602,7 +1602,7 @@ default comparison function simply raises "Failure".
|
|||
|
||||
\item "long (*hash)(value v)" \\
|
||||
The "hash" field contains a pointer to a C function that is called
|
||||
whenever Caml's generic hash operator (see module "Hashtbl") is
|
||||
whenever OCaml's generic hash operator (see module "Hashtbl") is
|
||||
applied to a custom block. The C function can return an arbitrary
|
||||
long integer representing the hash value of the data contained in the
|
||||
given custom block. The hash value must be compatible with the
|
||||
|
@ -1616,7 +1616,7 @@ the custom block is ignored during hash computation.
|
|||
\item "void (*serialize)(value v, unsigned long * wsize_32, unsigned long * wsize_64)" \\
|
||||
The "serialize" field contains a pointer to a C function that is
|
||||
called whenever the custom block needs to be serialized (marshaled)
|
||||
using the Caml functions "output_value" or "Marshal.to_...".
|
||||
using the OCaml functions "output_value" or "Marshal.to_...".
|
||||
For a custom block, those functions first write the identifier of the
|
||||
block (as given by the "identifier" field) to the output stream,
|
||||
then call the user-provided "serialize" function. That function is
|
||||
|
@ -1634,7 +1634,7 @@ serialize the custom block.
|
|||
\item "unsigned long (*deserialize)(void * dst)" \\
|
||||
The "deserialize" field contains a pointer to a C function that is
|
||||
called whenever a custom block with identifier "identifier" needs to
|
||||
be deserialized (un-marshaled) using the Caml functions "input_value"
|
||||
be deserialized (un-marshaled) using the OCaml functions "input_value"
|
||||
or "Marshal.from_...". This user-provided function is responsible for
|
||||
reading back the data written by the "serialize" operation, using the
|
||||
"deserialize_..." functions defined in "<caml/intext.h>" and listed
|
||||
|
@ -1654,7 +1654,7 @@ using "register_custom_operations" (see below).
|
|||
Note: the "finalize", "compare", "hash", "serialize" and "deserialize"
|
||||
functions attached to custom block descriptors must never trigger a
|
||||
garbage collection. Within these functions, do not call any of the
|
||||
Caml allocation functions, and do not perform a callback into Caml
|
||||
OCaml allocation functions, and do not perform a callback into OCaml
|
||||
code. Do not use "CAMLparam" to register the parameters to these
|
||||
functions, and do not use "CAMLreturn" to return the result.
|
||||
|
||||
|
@ -1665,12 +1665,12 @@ Custom blocks must be allocated via the "caml_alloc_custom" function.
|
|||
returns a fresh custom block, with room for \var{size} bytes of user
|
||||
data, and whose associated operations are given by \var{ops} (a
|
||||
pointer to a "struct custom_operations", usually statically allocated
|
||||
as a C global variable).
|
||||
as a C global variable).
|
||||
|
||||
The two parameters \var{used} and \var{max} are used to control the
|
||||
speed of garbage collection when the finalized object contains
|
||||
pointers to out-of-heap resources. Generally speaking, the
|
||||
Caml incremental major collector adjusts its speed relative to the
|
||||
OCaml incremental major collector adjusts its speed relative to the
|
||||
allocation rate of the program. The faster the program allocates, the
|
||||
harder the GC works in order to reclaim quickly unreachable blocks
|
||||
and avoid having large amount of ``floating garbage'' (unreferenced
|
||||
|
@ -1718,8 +1718,8 @@ has type "void *" and should be cast to the actual type of the data
|
|||
stored in the custom block.
|
||||
|
||||
The contents of custom blocks are not scanned by the garbage
|
||||
collector, and must therefore not contain any pointer inside the Caml
|
||||
heap. In other terms, never store a Caml "value" in a custom block,
|
||||
collector, and must therefore not contain any pointer inside the OCaml
|
||||
heap. In other terms, never store an OCaml "value" in a custom block,
|
||||
and do not use "Field", "Store_field" nor "caml_modify" to access the data
|
||||
part of a custom block. Conversely, any C data structure (not
|
||||
containing heap pointers) can be stored in a custom block.
|
||||
|
@ -1808,77 +1808,77 @@ collection, as described for "caml_alloc_custom".
|
|||
\section{Advanced topic: multithreading}
|
||||
\label{s:C-multithreading}
|
||||
|
||||
Using multiple threads (shared-memory concurrency) in a mixed Caml/C
|
||||
Using multiple threads (shared-memory concurrency) in a mixed OCaml/C
|
||||
application requires special precautions, which are described in this
|
||||
section.
|
||||
|
||||
\subsection{Registering threads created from C}
|
||||
|
||||
Callbacks from C to Caml are possible only if the calling thread is
|
||||
known to the Caml run-time system. Threads created from Caml (through
|
||||
Callbacks from C to OCaml are possible only if the calling thread is
|
||||
known to the OCaml run-time system. Threads created from OCaml (through
|
||||
the "Thread.create" function of the system threads library) are
|
||||
automatically known to the run-time system. If the application
|
||||
creates additional threads from C and wishes to callback into Caml
|
||||
creates additional threads from C and wishes to callback into OCaml
|
||||
code from these threads, it must first register them with the run-time
|
||||
system. The following functions are declared in the include file
|
||||
"<caml/threads.h>".
|
||||
|
||||
\begin{itemize}
|
||||
\item
|
||||
"caml_c_thread_register()" registers the calling thread with the Caml
|
||||
"caml_c_thread_register()" registers the calling thread with the OCaml
|
||||
run-time system. Returns 1 on success, 0 on error. Registering an
|
||||
already-register thread does nothing and returns 0.
|
||||
\item
|
||||
"caml_c_thread_unregister()" must be called before the thread
|
||||
terminates, to unregister it from the Caml run-time system.
|
||||
terminates, to unregister it from the OCaml run-time system.
|
||||
Returns 1 on success, 0 on error. If the calling thread was not
|
||||
previously registered, does nothing and returns 0.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Parallel execution of long-running C code}
|
||||
|
||||
The Caml run-time system is not reentrant: at any time, at most one
|
||||
thread can be executing Caml code or C code that uses the Caml
|
||||
The OCaml run-time system is not reentrant: at any time, at most one
|
||||
thread can be executing OCaml code or C code that uses the OCaml
|
||||
run-time system. Technically, this is enforced by a ``master lock''
|
||||
that any thread must hold while executing such code.
|
||||
|
||||
When Caml calls the C code implementing a primitive, the master lock
|
||||
When OCaml calls the C code implementing a primitive, the master lock
|
||||
is held, therefore the C code has full access to the facilities of the
|
||||
run-time system. However, no other thread can execute Caml code
|
||||
run-time system. However, no other thread can execute OCaml code
|
||||
concurrently with the C code of the primitive.
|
||||
|
||||
If a C primitive runs for a long time or performs potentially blocking
|
||||
input-output operations, it can explicitly release the master lock,
|
||||
enabling other Caml threads to run concurrently with its operations.
|
||||
The C code must re-acquire the master lock before returning to Caml.
|
||||
This is achieved with the following functions, declared in
|
||||
enabling other OCaml threads to run concurrently with its operations.
|
||||
The C code must re-acquire the master lock before returning to OCaml.
|
||||
This is achieved with the following functions, declared in
|
||||
the include file "<caml/threads.h>".
|
||||
|
||||
\begin{itemize}
|
||||
\item
|
||||
"caml_release_runtime_system()"
|
||||
The calling thread releases the master lock and other Caml resources,
|
||||
enabling other threads to run Caml code in parallel with the execution
|
||||
of the calling thread.
|
||||
The calling thread releases the master lock and other OCaml resources,
|
||||
enabling other threads to run OCaml code in parallel with the execution
|
||||
of the calling thread.
|
||||
\item
|
||||
"caml_acquire_runtime_system()"
|
||||
The calling thread re-acquires the master lock and other Caml
|
||||
resources. It may block until no other thread uses the Caml run-time
|
||||
The calling thread re-acquires the master lock and other OCaml
|
||||
resources. It may block until no other thread uses the OCaml run-time
|
||||
system.
|
||||
\end{itemize}
|
||||
|
||||
After "caml_release_runtime_system()" was called and until
|
||||
"caml_acquire_runtime_system()" is called, the C code must not access
|
||||
any Caml data, nor call any function of the run-time system, nor call
|
||||
back into Caml code. Consequently, arguments provided by Caml to the
|
||||
any OCaml data, nor call any function of the run-time system, nor call
|
||||
back into OCaml code. Consequently, arguments provided by OCaml to the
|
||||
C primitive must be copied into C data structures before calling
|
||||
"caml_release_runtime_system()", and results to be returned to Caml
|
||||
must be encoded as Caml values after "caml_acquire_runtime_system()"
|
||||
"caml_release_runtime_system()", and results to be returned to OCaml
|
||||
must be encoded as OCaml values after "caml_acquire_runtime_system()"
|
||||
returns.
|
||||
|
||||
Example: the following C primitive invokes "gethostbyname" to find the
|
||||
IP address of a host name. The "gethostbyname" function can block for
|
||||
a long time, so we choose to release the Caml run-time system while it
|
||||
a long time, so we choose to release the OCaml run-time system while it
|
||||
is running.
|
||||
\begin{verbatim}
|
||||
CAMLprim stub_gethostbyname(value vname)
|
||||
|
@ -1888,34 +1888,34 @@ CAMLprim stub_gethostbyname(value vname)
|
|||
struct hostent * h;
|
||||
|
||||
/* Copy the string argument to a C string, allocated outside the
|
||||
Caml heap. */
|
||||
OCaml heap. */
|
||||
name = stat_alloc(caml_string_length(vname) + 1);
|
||||
strcpy(name, String_val(vname));
|
||||
/* Release the Caml run-time system */
|
||||
/* Release the OCaml run-time system */
|
||||
caml_release_runtime_system();
|
||||
/* Resolve the name */
|
||||
h = gethostbyname(name);
|
||||
/* Re-acquire the Caml run-time system */
|
||||
/* Re-acquire the OCaml run-time system */
|
||||
caml_acquire_runtime_system();
|
||||
/* Encode the relevant fields of h as the Caml value vres */
|
||||
/* Encode the relevant fields of h as the OCaml value vres */
|
||||
... /* Omitted */
|
||||
/* Return to Caml */
|
||||
/* Return to OCaml */
|
||||
CAMLreturn (vres);
|
||||
}
|
||||
\end{verbatim}
|
||||
|
||||
Callbacks from C to Caml must be performed while holding the master
|
||||
lock to the Caml run-time system. This is naturally the case if the
|
||||
Callbacks from C to OCaml must be performed while holding the master
|
||||
lock to the OCaml run-time system. This is naturally the case if the
|
||||
callback is performed by a C primitive that did not release the
|
||||
run-time system. If the C primitive released the run-time system
|
||||
previously, or the callback is performed from other C code that was
|
||||
not invoked from Caml (e.g. an event loop in a GUI application), the
|
||||
not invoked from OCaml (e.g. an event loop in a GUI application), the
|
||||
run-time system must be acquired before the callback and released
|
||||
after:
|
||||
\begin{verbatim}
|
||||
caml_acquire_runtime_system();
|
||||
/* Resolve Caml function vfun to be invoked */
|
||||
/* Build Caml argument varg to the callback */
|
||||
/* Resolve OCaml function vfun to be invoked */
|
||||
/* Build OCaml argument varg to the callback */
|
||||
vres = callback(vfun, varg);
|
||||
/* Copy relevant parts of result vres to C data structures */
|
||||
caml_release_runtime_system();
|
||||
|
@ -1931,31 +1931,31 @@ names, declared in "<caml/signals.h>":
|
|||
"caml_acquire_runtime_system"
|
||||
\end{itemize}
|
||||
Intuition: a ``blocking section'' is a piece of C code that does not
|
||||
use the Caml run-time system, typically a blocking input/output operation.
|
||||
use the OCaml run-time system, typically a blocking input/output operation.
|
||||
|
||||
\section{Building mixed C/Caml libraries: "ocamlmklib"} \label{s-ocamlmklib}
|
||||
\section{Building mixed C/OCaml libraries: "ocamlmklib"} \label{s-ocamlmklib}
|
||||
|
||||
The "ocamlmklib" command facilitates the construction of libraries
|
||||
containing both Caml code and C code, and usable both in static
|
||||
containing both OCaml code and C code, and usable both in static
|
||||
linking and dynamic linking modes. This command is available under
|
||||
Windows since Objective Caml 3.11 and under other operating systems since
|
||||
Objective Caml 3.03.
|
||||
|
||||
The "ocamlmklib" command takes three kinds of arguments:
|
||||
\begin{itemize}
|
||||
\item Caml source files and object files (".cmo", ".cmx", ".ml")
|
||||
comprising the Caml part of the library;
|
||||
\item OCaml source files and object files (".cmo", ".cmx", ".ml")
|
||||
comprising the OCaml part of the library;
|
||||
\item C object files (".o", ".a", respectively, ".obj", ".lib")
|
||||
comprising the C part of the library;
|
||||
\item Support libraries for the C part ("-l"\var{lib}).
|
||||
\end{itemize}
|
||||
It generates the following outputs:
|
||||
\begin{itemize}
|
||||
\item A Caml bytecode library ".cma" incorporating the ".cmo" and
|
||||
".ml" Caml files given as arguments, and automatically referencing the
|
||||
\item An OCaml bytecode library ".cma" incorporating the ".cmo" and
|
||||
".ml" OCaml files given as arguments, and automatically referencing the
|
||||
C library generated with the C object files.
|
||||
\item A Caml native-code library ".cmxa" incorporating the ".cmx" and
|
||||
".ml" Caml files given as arguments, and automatically referencing the
|
||||
\item An OCaml native-code library ".cmxa" incorporating the ".cmx" and
|
||||
".ml" OCaml files given as arguments, and automatically referencing the
|
||||
C library generated with the C object files.
|
||||
\item If dynamic linking is supported on the target platform, a
|
||||
".so" (respectively, ".dll") shared library built from the C object files given as arguments,
|
||||
|
@ -1981,7 +1981,7 @@ libraries ("-l"\var{lib}).
|
|||
the bytecode compiler.
|
||||
\item["-ocamlopt" \var{cmd}] Use \var{cmd} instead of "ocamlopt" to call
|
||||
the native-code compiler.
|
||||
\item["-o" \var{output}] Set the name of the generated Caml library.
|
||||
\item["-o" \var{output}] Set the name of the generated OCaml library.
|
||||
"ocamlmklib" will generate \var{output}".cma" and/or \var{output}".cmxa".
|
||||
If not specified, defaults to "a".
|
||||
\item["-oc" \var{outputc}] Set the name of the generated C library.
|
||||
|
@ -1990,12 +1990,12 @@ libraries are supported) and "lib"\var{outputc}".a".
|
|||
If not specified, defaults to the output name given with "-o".
|
||||
\end{options}
|
||||
|
||||
\paragraph{Example} Consider a Caml interface to the standard "libz"
|
||||
\paragraph{Example} Consider an OCaml interface to the standard "libz"
|
||||
C library for reading and writing compressed files. Assume this
|
||||
library resides in "/usr/local/zlib". This interface is
|
||||
composed of a Caml part "zip.cmo"/"zip.cmx" and a C part "zipstubs.o"
|
||||
composed of an OCaml part "zip.cmo"/"zip.cmx" and a C part "zipstubs.o"
|
||||
containing the stub code around the "libz" entry points. The
|
||||
following command builds the Caml libraries "zip.cma" and "zip.cmxa",
|
||||
following command builds the OCaml libraries "zip.cma" and "zip.cmxa",
|
||||
as well as the companion C libraries "dllzip.so" and "libzip.a":
|
||||
\begin{verbatim}
|
||||
ocamlmklib -o zip zip.cmo zip.cmx zipstubs.o -lz -L/usr/local/zlib
|
||||
|
|
|
@ -26,7 +26,7 @@ expressions with attached semantic actions, in the style of
|
|||
\begin{alltt}
|
||||
ocamllex \var{lexer}.mll
|
||||
\end{alltt}
|
||||
produces Caml code for a lexical analyzer in file \var{lexer}".ml".
|
||||
produces OCaml code for a lexical analyzer in file \var{lexer}".ml".
|
||||
This file defines one lexing function per entry point in the lexer
|
||||
definition. These functions have the same names as the entry
|
||||
points. Lexing functions take as argument a lexer buffer, and return
|
||||
|
@ -51,7 +51,7 @@ The following command-line options are recognized by "ocamllex".
|
|||
|
||||
\item["-ml"]
|
||||
Output code that does not use OCaml's built-in automata
|
||||
interpreter. Instead, the automaton is encoded by Caml functions.
|
||||
interpreter. Instead, the automaton is encoded by OCaml functions.
|
||||
This option mainly is useful for debugging "ocamllex", using it for
|
||||
production lexers is not recommended.
|
||||
|
||||
|
@ -63,10 +63,10 @@ The default is the input file name with its extension replaced by ".ml".
|
|||
Quiet mode. "ocamllex" normally outputs informational messages
|
||||
to standard output. They are suppressed if option "-q" is used.
|
||||
|
||||
\item["-v" or "-version"]
|
||||
\item["-v" or "-version"]
|
||||
Print version string and exit.
|
||||
|
||||
\item["-vnum"]
|
||||
\item["-vnum"]
|
||||
Print short version number and exit.
|
||||
|
||||
\item["-help" or "--help"]
|
||||
|
@ -91,13 +91,13 @@ and \ldots
|
|||
\{ \var{trailer} \}
|
||||
\end{alltt}
|
||||
\endgroup
|
||||
Comments are delimited by "(*" and "*)", as in Caml.
|
||||
Comments are delimited by "(*" and "*)", as in OCaml.
|
||||
The "parse" keyword, can be replaced by the "shortest" keyword, with
|
||||
the semantic consequences explained below.
|
||||
|
||||
|
||||
\subsection{Header and trailer}
|
||||
The {\it header} and {\it trailer} sections are arbitrary Caml
|
||||
The {\it header} and {\it trailer} sections are arbitrary OCaml
|
||||
text enclosed in curly braces. Either or both can be omitted. If
|
||||
present, the header text is copied as is at the beginning of the
|
||||
output file and the trailer text at the end. Typically, the
|
||||
|
@ -115,12 +115,12 @@ In regular expressions that follow this declaration, the identifier
|
|||
|
||||
\subsection{Entry points}
|
||||
|
||||
The names of the entry points must be valid identifiers for Caml
|
||||
The names of the entry points must be valid identifiers for OCaml
|
||||
values (starting with a lowercase letter).
|
||||
Similarily, the arguments \texttt{\var{arg$_1$}\ldots{}
|
||||
\var{arg$_n$}} must be valid identifiers for Caml.
|
||||
Each entry point becomes a
|
||||
Caml function that takes $n+1$ arguments,
|
||||
\var{arg$_n$}} must be valid identifiers for OCaml.
|
||||
Each entry point becomes an
|
||||
OCaml function that takes $n+1$ arguments,
|
||||
the extra implicit last argument being of type "Lexing.lexbuf".
|
||||
Characters are read from the "Lexing.lexbuf" argument and matched
|
||||
against the regular expressions provided in the rule, until a prefix
|
||||
|
@ -145,7 +145,7 @@ may facilitate the use of "ocamllex" as a simple text processing tool.
|
|||
\subsection{Regular expressions}
|
||||
|
||||
The regular expressions are in the style of "lex", with a more
|
||||
Caml-like syntax.
|
||||
OCaml-like syntax.
|
||||
\begin{syntax}
|
||||
regexp:
|
||||
\ldots
|
||||
|
@ -192,7 +192,7 @@ Match the difference of the two specified character sets.
|
|||
|
||||
\item[@regexp '*'@]
|
||||
(Repetition.) Match the concatenation of zero or more
|
||||
strings that match @regexp@.
|
||||
strings that match @regexp@.
|
||||
|
||||
\item[@regexp '+'@]
|
||||
(Strict repetition.) Match the concatenation of one or more
|
||||
|
@ -225,7 +225,7 @@ then concatenation, then "|" (alternation), then "as".
|
|||
|
||||
\subsection{Actions}
|
||||
|
||||
The actions are arbitrary Caml expressions. They are evaluated in
|
||||
The actions are arbitrary OCaml expressions. They are evaluated in
|
||||
a context where the identifiers defined by using the "as" construct
|
||||
are bound to subparts of the matched string.
|
||||
Additionally, "lexbuf" is bound to the current lexer
|
||||
|
@ -291,7 +291,7 @@ can be matched without binding this variable.
|
|||
\end{itemize}
|
||||
For instance, in
|
||||
\verb+('a' as x) | ( 'a' (_ as x) )+ the variable \verb+x+ is of type
|
||||
"char", whereas in
|
||||
"char", whereas in
|
||||
\verb+("ab" as x) | ( 'a' (_ as x) ? )+ the variable \verb+x+ is of type
|
||||
"string option".
|
||||
|
||||
|
@ -322,7 +322,7 @@ Assuming the input file is \var{grammar}".mly", executing
|
|||
\begin{alltt}
|
||||
ocamlyacc \var{options} \var{grammar}.mly
|
||||
\end{alltt}
|
||||
produces Caml code for a parser in the file \var{grammar}".ml",
|
||||
produces OCaml code for a parser in the file \var{grammar}".ml",
|
||||
and its interface in file \var{grammar}".mli".
|
||||
|
||||
The generated module defines one parsing function per entry point in
|
||||
|
@ -352,11 +352,11 @@ Grammar definitions have the following format:
|
|||
|
||||
Comments are enclosed between \verb|/*| and \verb|*/| (as in C) in the
|
||||
``declarations'' and ``rules'' sections, and between \verb|(*| and
|
||||
\verb|*)| (as in Caml) in the ``header'' and ``trailer'' sections.
|
||||
\verb|*)| (as in OCaml) in the ``header'' and ``trailer'' sections.
|
||||
|
||||
\subsection{Header and trailer}
|
||||
|
||||
The header and the trailer sections are Caml code that is copied
|
||||
The header and the trailer sections are OCaml code that is copied
|
||||
as is into file \var{grammar}".ml". Both sections are optional. The header
|
||||
goes at the beginning of the output file; it usually contains
|
||||
"open" directives and auxiliary functions required by the semantic
|
||||
|
@ -378,7 +378,7 @@ Declare the given symbols @constr \ldots constr@ as tokens with an
|
|||
attached attribute of the
|
||||
given type. These symbols are added as constructors with arguments of
|
||||
the given type for the "token" concrete type. The @typexpr@ part is
|
||||
an arbitrary Caml type expression, except that all type
|
||||
an arbitrary OCaml type expression, except that all type
|
||||
constructor names must be fully qualified (e.g. "Modname.typename")
|
||||
for all types except standard built-in types, even if the proper
|
||||
\verb|open| directives (e.g. \verb|open Modname|) were given in the
|
||||
|
@ -398,7 +398,7 @@ Specify the type of the semantic attributes for the given symbols.
|
|||
This is mandatory for start symbols only. Other nonterminal symbols
|
||||
need not be given types by hand: these types will be inferred when
|
||||
running the output files through the OCaml compiler (unless the
|
||||
\verb"-s" option is in effect). The @typexpr@ part is an arbitrary Caml
|
||||
\verb"-s" option is in effect). The @typexpr@ part is an arbitrary OCaml
|
||||
type expression, except that all type constructor names must be
|
||||
fully qualified, as explained above for "%token".
|
||||
|
||||
|
@ -461,7 +461,7 @@ right-hand side part, to override the default precedence and
|
|||
associativity of the rule with the precedence and associativity of the
|
||||
given symbol.
|
||||
|
||||
Semantic actions are arbitrary Caml expressions, that
|
||||
Semantic actions are arbitrary OCaml expressions, that
|
||||
are evaluated to produce the semantic attribute attached to
|
||||
the defined nonterminal. The semantic actions can access the
|
||||
semantic attributes of the symbols in the right-hand side of
|
||||
|
@ -474,7 +474,7 @@ resynchronization points, as in "yacc".
|
|||
|
||||
Actions occurring in the middle of rules are not supported.
|
||||
|
||||
Nonterminal symbols are like regular Caml symbols, except that they
|
||||
Nonterminal symbols are like regular OCaml symbols, except that they
|
||||
cannot end with "'" (single quote).
|
||||
|
||||
\subsection{Error handling}
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
\pdfchapter{Native-code compilation (ocamlopt)}
|
||||
|
||||
This chapter describes the OCaml high-performance
|
||||
native-code compiler "ocamlopt", which compiles Caml source files to
|
||||
native-code compiler "ocamlopt", which compiles OCaml source files to
|
||||
native code object files and link these object files to produce
|
||||
standalone executables.
|
||||
standalone executables.
|
||||
|
||||
The native-code compiler is only available on certain platforms.
|
||||
It produces code that runs faster than the bytecode produced by
|
||||
|
@ -45,7 +45,7 @@ and \var{x}".cmx", containing extra information for linking and
|
|||
optimization of the clients of the unit. The compiled implementation
|
||||
should always be referred to under the name \var{x}".cmx" (when given
|
||||
a ".o" or ".obj" file, "ocamlopt" assumes that it contains code compiled from C,
|
||||
not from Caml).
|
||||
not from OCaml).
|
||||
|
||||
The implementation is checked against the interface file \var{x}".mli"
|
||||
(if it exists) as described in the manual for "ocamlc"
|
||||
|
@ -54,7 +54,7 @@ The implementation is checked against the interface file \var{x}".mli"
|
|||
\item
|
||||
Arguments ending in ".cmx" are taken to be compiled object code. These
|
||||
files are linked together, along with the object files obtained
|
||||
by compiling ".ml" arguments (if any), and the Caml standard
|
||||
by compiling ".ml" arguments (if any), and the OCaml standard
|
||||
library, to produce a native-code executable program. The order in
|
||||
which ".cmx" and ".ml" arguments are presented on the command line is
|
||||
relevant: compilation units are initialized in that order at
|
||||
|
@ -243,7 +243,7 @@ is given, specify the name of plugin file produced.
|
|||
|
||||
\item["-output-obj"]
|
||||
Cause the linker to produce a C object file instead of an executable
|
||||
file. This is useful to wrap Caml code as a C library,
|
||||
file. This is useful to wrap OCaml code as a C library,
|
||||
callable from any C program. See chapter~\ref{c:intf-c},
|
||||
section~\ref{s:embedded-code}. The name of the output object file
|
||||
must be set with the "-o" option.
|
||||
|
@ -327,11 +327,11 @@ code for the source file \var{x}".ml" is saved in the file \var{x}".s".
|
|||
\item["-shared"]
|
||||
Build a plugin (usually ".cmxs") that can be dynamically loaded with
|
||||
the "Dynlink" module. The name of the plugin must be
|
||||
set with the "-o" option. A plugin can include a number of Caml
|
||||
set with the "-o" option. A plugin can include a number of OCaml
|
||||
modules and libraries, and extra native objects (".o", ".obj", ".a",
|
||||
".lib" files). Building native plugins is only supported for some
|
||||
operating system. Under some systems (currently,
|
||||
only Linux AMD 64), all the Caml code linked in a plugin must have
|
||||
only Linux AMD 64), all the OCaml code linked in a plugin must have
|
||||
been compiled without the "-nodynlink" flag. Some constraints might also
|
||||
apply to the way the extra native objects have been compiled (under
|
||||
Linux AMD 64, they must contain only position-independent code).
|
||||
|
@ -481,7 +481,7 @@ See section~\ref{s:comp-errors}.
|
|||
Executables generated by "ocamlopt" are native, stand-alone executable
|
||||
files that can be invoked directly. They do
|
||||
not depend on the "ocamlrun" bytecode runtime system nor on
|
||||
dynamically-loaded C/Caml stub libraries.
|
||||
dynamically-loaded C/OCaml stub libraries.
|
||||
|
||||
During execution of an "ocamlopt"-generated executable,
|
||||
the following environment variables are also consulted:
|
||||
|
@ -509,7 +509,7 @@ allocation in the heap. That is, if a signal is delivered while in a
|
|||
piece of code that does not allocate, its handler will not be called
|
||||
until the next heap allocation.
|
||||
|
||||
\item Stack overflow, typically caused by excessively deep recursion,
|
||||
\item Stack overflow, typically caused by excessively deep recursion,
|
||||
is handled in one of the following ways, depending on the
|
||||
platform used:
|
||||
\begin{itemize}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
This chapter describes how the execution of OCaml
|
||||
programs can be profiled, by recording how many times functions are
|
||||
called, branches of conditionals are taken, \ldots
|
||||
called, branches of conditionals are taken, \ldots
|
||||
|
||||
\section{Compiling for profiling}
|
||||
|
||||
|
@ -91,7 +91,7 @@ The following options are recognized by "ocamlprof":
|
|||
|
||||
\begin{options}
|
||||
|
||||
\item["-f" \var{dumpfile}]
|
||||
\item["-f" \var{dumpfile}]
|
||||
Specifies an alternate dump file of profiling information to be read.
|
||||
|
||||
\item["-F" \var{string}]
|
||||
|
@ -135,11 +135,11 @@ the program:
|
|||
./myprog
|
||||
gprof myprog
|
||||
\end{alltt}
|
||||
Caml function names in the output of "gprof" have the following format:
|
||||
OCaml function names in the output of "gprof" have the following format:
|
||||
\begin{alltt}
|
||||
\var{Module-name}_\var{function-name}_\var{unique-number}
|
||||
\end{alltt}
|
||||
Other functions shown are either parts of the Caml run-time system or
|
||||
Other functions shown are either parts of the OCaml run-time system or
|
||||
external C functions linked with the program.
|
||||
|
||||
The output of "gprof" is described in the Unix manual page for
|
||||
|
|
|
@ -20,7 +20,7 @@ The usage for "ocamlrun" is:
|
|||
The first non-option argument is taken to be the name of the file
|
||||
containing the executable bytecode. (That file is searched in the
|
||||
executable path as well as in the current directory.) The remaining
|
||||
arguments are passed to the Caml program, in the string array
|
||||
arguments are passed to the OCaml program, in the string array
|
||||
"Sys.argv". Element 0 of this array is the name of the
|
||||
bytecode executable file; elements 1 to \var{n} are the remaining
|
||||
arguments \nth{arg}{1} to \nth{arg}{n}.
|
||||
|
@ -28,16 +28,16 @@ arguments \nth{arg}{1} to \nth{arg}{n}.
|
|||
As mentioned in chapter~\ref{c:camlc}, the bytecode executable files
|
||||
produced by the "ocamlc" command are self-executable, and manage to
|
||||
launch the "ocamlrun" command on themselves automatically. That is,
|
||||
assuming "caml.out" is a bytecode executable file,
|
||||
assuming "a.out" is a bytecode executable file,
|
||||
\begin{alltt}
|
||||
caml.out \nth{arg}{1} ... \nth{arg}{n}
|
||||
a.out \nth{arg}{1} ... \nth{arg}{n}
|
||||
\end{alltt}
|
||||
works exactly as
|
||||
\begin{alltt}
|
||||
ocamlrun caml.out \nth{arg}{1} ... \nth{arg}{n}
|
||||
ocamlrun a.out \nth{arg}{1} ... \nth{arg}{n}
|
||||
\end{alltt}
|
||||
Notice that it is not possible to pass options to "ocamlrun" when
|
||||
invoking "caml.out" directly.
|
||||
invoking "a.out" directly.
|
||||
|
||||
\begin{windows}
|
||||
Under several versions of Windows, bytecode executable files are
|
||||
|
@ -67,13 +67,13 @@ section~\ref{s-ocamlrun-dllpath}).
|
|||
\item["-p"]
|
||||
Print the names of the primitives known to this version of
|
||||
"ocamlrun" and exit.
|
||||
\item["-v"]
|
||||
\item["-v"]
|
||||
Direct the memory manager to print some progress messages on
|
||||
standard error. This is equivalent to setting "v=63" in the
|
||||
"OCAMLRUNPARAM" environment variable (see below).
|
||||
\item["-version"]
|
||||
\item["-version"]
|
||||
Print version string and exit.
|
||||
\item["-vnum"]
|
||||
\item["-vnum"]
|
||||
Print short version number and exit.
|
||||
|
||||
\end{options}
|
||||
|
@ -91,7 +91,7 @@ The following environment variables are also consulted:
|
|||
dynamic loading (see section~\ref{s-ocamlrun-dllpath}). If not set,
|
||||
default to the library directory specified when compiling OCaml.
|
||||
|
||||
\item["OCAMLRUNPARAM"] Set the runtime system options
|
||||
\item["OCAMLRUNPARAM"] Set the runtime system options
|
||||
and garbage collection parameters.
|
||||
(If "OCAMLRUNPARAM" is not set, "CAMLRUNPARAM" will be used instead.)
|
||||
This variable must be a sequence of parameter specifications.
|
||||
|
@ -99,14 +99,14 @@ The following environment variables are also consulted:
|
|||
sign, a decimal number (or an hexadecimal number prefixed by "0x"),
|
||||
and an optional multiplier. There are
|
||||
nine options, six of which correspond to the fields of the
|
||||
"control" record documented in
|
||||
"control" record documented in
|
||||
\ifouthtml
|
||||
\ahref{libref/Gc.html}{Module \texttt{Gc}}.
|
||||
\else
|
||||
section~\ref{Gc}.
|
||||
\fi
|
||||
\begin{options}
|
||||
\item[b] (backtrace) Trigger the printing of a stack backtrace
|
||||
\item[b] (backtrace) Trigger the printing of a stack backtrace
|
||||
when an uncaught exception aborts the program.
|
||||
This option takes no argument.
|
||||
\item[p] (parser trace) Turn on debugging support for
|
||||
|
@ -189,7 +189,7 @@ directories listed in the file "/etc/ld.so.conf" and the environment
|
|||
variable "LD_LIBRARY_PATH". Under Windows, these include the Windows
|
||||
system directories, plus the directories listed in the "PATH"
|
||||
environment variable.
|
||||
\end{enumerate}
|
||||
\end{enumerate}
|
||||
|
||||
\section{Common errors}
|
||||
|
||||
|
@ -248,7 +248,7 @@ to "ocamlrun", or with the "OCAMLRUNPARAM" environment variable set to
|
|||
messages, this is probably a looping recursive function. If it
|
||||
displays lots of ``"Growing heap"\ldots'' messages, with the heap size
|
||||
growing slowly, this is probably an attempt to construct a data
|
||||
structure with too many (infinitely many?) cells. If it displays few
|
||||
structure with too many (infinitely many?) cells. If it displays few
|
||||
``"Growing heap"\ldots'' messages, but with a huge increment in the
|
||||
heap size, this is probably an attempt to build an excessively large
|
||||
array or string.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
This chapter describes the toplevel system for OCaml, that permits interactive use of the OCaml system
|
||||
through a read-eval-print loop. In this mode, the system repeatedly
|
||||
reads Caml phrases from the input, then typechecks, compile and
|
||||
reads OCaml phrases from the input, then typechecks, compile and
|
||||
evaluate them, then prints the inferred type and result value, if
|
||||
any. The system prints a "#" (sharp) prompt before reading each
|
||||
phrase.
|
||||
|
@ -342,7 +342,7 @@ results in the error ``Reference to undefined global `\ldots'\,''.
|
|||
Note that entering "open "\var{Mod} merely accesses the compiled
|
||||
interface (".cmi" file) for \var{Mod}, but does not load the
|
||||
implementation of \var{Mod}, and does not cause any error if no
|
||||
implementation of \var{Mod} has been loaded. The error
|
||||
implementation of \var{Mod} has been loaded. The error
|
||||
``reference to undefined global \var{Mod}'' will occur only when
|
||||
executing a value or module definition that refers to \var{Mod}.
|
||||
|
||||
|
@ -355,7 +355,7 @@ error messages.
|
|||
|
||||
\item[Cannot find file \var{filename}]
|
||||
The named file could not be found in the current directory, nor in the
|
||||
directories of the search path.
|
||||
directories of the search path.
|
||||
|
||||
If \var{filename} has the format \var{mod}".cmi", this
|
||||
means you have referenced the compilation unit \var{mod}, but its
|
||||
|
@ -383,7 +383,7 @@ with "#load". See section~\ref{s:toplevel-modules} above.
|
|||
\section{Building custom toplevel systems: "ocamlmktop"}
|
||||
|
||||
The "ocamlmktop" command builds OCaml toplevels that
|
||||
contain user code preloaded at start-up.
|
||||
contain user code preloaded at start-up.
|
||||
|
||||
The "ocamlmktop" command takes as argument a set of ".cmo" and ".cma"
|
||||
files, and links them with the object files that implement the OCaml toplevel.
|
||||
|
|
|
@ -35,26 +35,26 @@ systems, including Linux and \hbox{MacOS~X}.
|
|||
|
||||
\section*{License}
|
||||
|
||||
The OCaml system is copyright \copyright\ 1996--2011
|
||||
The OCaml system is copyright \copyright\ 1996--2012
|
||||
Institut National de Recherche en Informatique et en
|
||||
Automatique (INRIA).
|
||||
INRIA holds all ownership rights to the OCaml system.
|
||||
INRIA holds all ownership rights to the OCaml system.
|
||||
|
||||
The OCaml system is open source and can be freely
|
||||
redistributed. See the file "LICENSE" in the distribution for
|
||||
licensing information.
|
||||
|
||||
The present documentation is copyright \copyright\ \number\year\
|
||||
The present documentation is copyright \copyright\ \number\year\
|
||||
Institut National de Recherche en Informatique et en
|
||||
Automatique (INRIA). The OCaml documentation and user's
|
||||
manual may be reproduced and distributed in whole or
|
||||
in part, subject to the following conditions:
|
||||
in part, subject to the following conditions:
|
||||
\begin{itemize}
|
||||
\item The copyright notice above and this permission notice must be
|
||||
preserved complete on all complete or partial copies.
|
||||
\item Any translation or derivative work of the OCaml
|
||||
documentation and user's manual must be approved by the authors in
|
||||
writing before distribution.
|
||||
writing before distribution.
|
||||
\item If you distribute the OCaml
|
||||
documentation and user's manual in part, instructions for obtaining
|
||||
the complete version of this manual must be included, and a
|
||||
|
@ -73,7 +73,7 @@ additional information on OCaml.
|
|||
\end{latexonly}
|
||||
|
||||
\begin{htmlonly}
|
||||
The complete OCaml distribution can be accessed via the
|
||||
The complete OCaml distribution can be accessed via the
|
||||
\url{http://caml.inria.fr/}{Caml Web site}.
|
||||
The \url{http://caml.inria.fr/}{Caml Web site}
|
||||
contains a lot of additional information on OCaml.
|
||||
|
|
|
@ -3,32 +3,32 @@
|
|||
|
||||
The "bigarray" library implements large, multi-dimensional, numerical
|
||||
arrays. These arrays are called ``big arrays'' to distinguish them
|
||||
from the standard Caml arrays described in
|
||||
from the standard OCaml arrays described in
|
||||
\ifouthtml
|
||||
\ahref{libref/Array.html}{Module \texttt{Array}}.
|
||||
\else
|
||||
section~\ref{Array}.
|
||||
\fi
|
||||
The main differences between ``big arrays'' and standard Caml arrays
|
||||
The main differences between ``big arrays'' and standard OCaml arrays
|
||||
are as follows:
|
||||
\begin{itemize}
|
||||
\item Big arrays are not limited in size, unlike Caml arrays
|
||||
\item Big arrays are not limited in size, unlike OCaml arrays
|
||||
("float array" are limited to 2097151 elements on a 32-bit platform,
|
||||
other "array" types to 4194303 elements).
|
||||
\item Big arrays are multi-dimensional. Any number of dimensions
|
||||
between 1 and 16 is supported. In contrast, Caml arrays are
|
||||
between 1 and 16 is supported. In contrast, OCaml arrays are
|
||||
mono-dimensional and require encoding multi-dimensional arrays as
|
||||
arrays of arrays.
|
||||
\item Big arrays can only contain integers and floating-point
|
||||
numbers, while Caml arrays can contain arbitrary Caml data types.
|
||||
numbers, while OCaml arrays can contain arbitrary OCaml data types.
|
||||
However, big arrays provide more space-efficient storage of integer
|
||||
and floating-point elements, in particular because they support
|
||||
``small'' types such as single-precision floats and 8 and 16-bit
|
||||
integers, in addition to the standard Caml types of double-precision
|
||||
integers, in addition to the standard OCaml types of double-precision
|
||||
floats and 32 and 64-bit integers.
|
||||
\item The memory layout of big arrays is entirely compatible with that
|
||||
of arrays in C and Fortran, allowing large arrays to be passed back
|
||||
and forth between Caml code and C / Fortran code with no data copying
|
||||
and forth between OCaml code and C / Fortran code with no data copying
|
||||
at all.
|
||||
\item Big arrays support interesting high-level operations that normal
|
||||
arrays do not provide efficiently, such as extracting sub-arrays and
|
||||
|
@ -59,9 +59,9 @@ start "ocaml" and type "#load \"bigarray.cma\";;".
|
|||
\input{Bigarray.tex}
|
||||
\fi
|
||||
|
||||
\section{Big arrays in the Caml-C interface}
|
||||
\section{Big arrays in the OCaml-C interface}
|
||||
|
||||
C stub code that interface C or Fortran code with Caml code, as
|
||||
C stub code that interface C or Fortran code with OCaml code, as
|
||||
described in chapter~\ref{c:intf-c}, can exploit big arrays as
|
||||
follows.
|
||||
|
||||
|
@ -71,14 +71,14 @@ The include file "<caml/bigarray.h>" must be included in the C stub
|
|||
file. It declares the functions, constants and macros discussed
|
||||
below.
|
||||
|
||||
\subsection{Accessing a Caml bigarray from C or Fortran}
|
||||
\subsection{Accessing an OCaml bigarray from C or Fortran}
|
||||
|
||||
If \var{v} is a Caml "value" representing a big array, the expression
|
||||
If \var{v} is a OCaml "value" representing a big array, the expression
|
||||
"Data_bigarray_val("\var{v}")" returns a pointer to the data part of the array.
|
||||
This pointer is of type "void *" and can be cast to the appropriate C
|
||||
type for the array (e.g. "double []", "char [][10]", etc).
|
||||
|
||||
Various characteristics of the Caml big array can be consulted from C
|
||||
Various characteristics of the OCaml big array can be consulted from C
|
||||
as follows:
|
||||
\begin{tableau}{|l|l|}{C expression}{Returns}
|
||||
\entree{"Bigarray_val("\var{v}")->num_dims"}{number of dimensions}
|
||||
|
@ -117,16 +117,16 @@ to a C function and a Fortran function.
|
|||
}
|
||||
\end{verbatim}
|
||||
|
||||
\subsection{Wrapping a C or Fortran array as a Caml big array}
|
||||
\subsection{Wrapping a C or Fortran array as an OCaml big array}
|
||||
|
||||
A pointer \var{p} to an already-allocated C or Fortran array can be
|
||||
wrapped and returned to Caml as a big array using the "alloc_bigarray"
|
||||
wrapped and returned to OCaml as a big array using the "alloc_bigarray"
|
||||
or "alloc_bigarray_dims" functions.
|
||||
\begin{itemize}
|
||||
\item
|
||||
"alloc_bigarray("\var{kind} "|" \var{layout}, \var{numdims}, \var{p}, \var{dims}")"
|
||||
|
||||
Return a Caml big array wrapping the data pointed to by \var{p}.
|
||||
Return an OCaml big array wrapping the data pointed to by \var{p}.
|
||||
\var{kind} is the kind of array elements (one of the "BIGARRAY_"
|
||||
kind constants above). \var{layout} is "BIGARRAY_C_LAYOUT" for an
|
||||
array with C layout and "BIGARRAY_FORTRAN_LAYOUT" for an array with
|
||||
|
@ -144,7 +144,7 @@ passed as an array.
|
|||
\end{itemize}
|
||||
%
|
||||
The following example illustrates how statically-allocated C and
|
||||
Fortran arrays can be made available to Caml.
|
||||
Fortran arrays can be made available to OCaml.
|
||||
\begin{verbatim}
|
||||
extern long my_c_array[100][200];
|
||||
extern float my_fortran_array_[300][400];
|
||||
|
|
|
@ -79,7 +79,7 @@ indentation and line breaking \\
|
|||
\subsubsection{System interface:}
|
||||
\begin{tabular}{lll}
|
||||
"Arg" & p.~\pageref{Arg} & parsing of command line arguments \\
|
||||
"Callback" & p.~\pageref{Callback} & registering Caml functions to
|
||||
"Callback" & p.~\pageref{Callback} & registering OCaml functions to
|
||||
be called from C \\
|
||||
"Filename" & p.~\pageref{Filename} & operations on file names \\
|
||||
"Gc" & p.~\pageref{Gc} & memory management control and statistics \\
|
||||
|
@ -94,7 +94,7 @@ be called from C \\
|
|||
\item \ahref{libref/Array.html}{Module \texttt{Array}: array operations}
|
||||
\item \ahref{libref/ArrayLabels.html}{Module \texttt{ArrayLabels}: array operations (with labels)}
|
||||
\item \ahref{libref/Buffer.html}{Module \texttt{Buffer}: extensible string buffers}
|
||||
\item \ahref{libref/Callback.html}{Module \texttt{Callback}: registering Caml values with the C runtime}
|
||||
\item \ahref{libref/Callback.html}{Module \texttt{Callback}: registering OCaml values with the C runtime}
|
||||
\item \ahref{libref/Char.html}{Module \texttt{Char}: character operations}
|
||||
\item \ahref{libref/Complex.html}{Module \texttt{Complex}: Complex numbers}
|
||||
\item \ahref{libref/Digest.html}{Module \texttt{Digest}: MD5 message digest}
|
||||
|
|
|
@ -267,7 +267,7 @@ function component of a safe module is applied during this computation
|
|||
\section{Private types}
|
||||
\ikwd{private\@\texttt{private}}
|
||||
|
||||
Private type declarations in module signatures, of the form
|
||||
Private type declarations in module signatures, of the form
|
||||
"type t = private ...", enable libraries to
|
||||
reveal some, but not all aspects of the implementation of a type to
|
||||
clients of the library. In this respect, they strike a middle ground
|
||||
|
@ -332,7 +332,7 @@ type-equation:
|
|||
\end{syntax}
|
||||
Unlike a regular type abbreviation, a private type abbreviation
|
||||
declares a type that is distinct from its implementation type @typexpr@.
|
||||
However, coercions from the type to @typexpr@ are permitted.
|
||||
However, coercions from the type to @typexpr@ are permitted.
|
||||
Moreover, the compiler ``knows'' the implementation type and can take
|
||||
advantage of this knowledge to perform type-directed optimizations.
|
||||
For ambiguity reasons, @typexpr@ cannot be an object or polymorphic
|
||||
|
@ -644,7 +644,7 @@ encapsulated in this value.
|
|||
The @package-type@ syntactic class appearing in the @('module'
|
||||
module-expr ':' package-type)@ expressions, the @('val' expr ':'
|
||||
package-type)@ module expressions and the @('module' package-type)@
|
||||
type expression represents a subset of module types.
|
||||
type expression represents a subset of module types.
|
||||
This subset consists of named module types with optional constraints
|
||||
of a limited form: only non-parametrized types can be specified. For
|
||||
type-checking purposes, package types are compared by path equality on
|
||||
|
@ -658,7 +658,7 @@ module binding @'let'~M = ("val" expr_1 ":" package-type) "in" expr_2@,
|
|||
however.
|
||||
|
||||
\paragraph{Basic example} A typical use of first-class modules is to
|
||||
select at run-time among several implementations of a signatures.
|
||||
select at run-time among several implementations of a signatures.
|
||||
Each implementation is a structure that we can encapsulate as a
|
||||
first-class module, then store in a data structure such as a hash
|
||||
table:
|
||||
|
@ -708,7 +708,7 @@ The type inferred for this function is "(module Set.S with type elt =
|
|||
type t = s
|
||||
let compare = cmp
|
||||
end) in
|
||||
(module S : Set.S with type elt = s)
|
||||
(module S : Set.S with type elt = s)
|
||||
\end{verbatim}
|
||||
|
||||
This function has type "('a -> 'a -> int) -> (module Set.S with type elt = 'a)".
|
||||
|
@ -809,7 +809,7 @@ polymorphic recursion.
|
|||
(Introduced in OCaml 3.12)
|
||||
|
||||
\begin{syntax}
|
||||
module-type:
|
||||
module-type:
|
||||
...
|
||||
| 'module' 'type' 'of' module-expr
|
||||
\end{syntax}
|
||||
|
|
|
@ -202,7 +202,7 @@ otherwise:
|
|||
new object of open or private
|
||||
rec sig struct then to true
|
||||
try type val virtual when while
|
||||
with
|
||||
with
|
||||
\end{verbatim}
|
||||
%
|
||||
The following character sequences are also keywords:
|
||||
|
@ -237,7 +237,7 @@ linenum-directive:
|
|||
;
|
||||
\end{syntax}
|
||||
|
||||
Preprocessors that generate Caml source code can insert line number
|
||||
Preprocessors that generate OCaml source code can insert line number
|
||||
directives in their output so that error messages produced by the
|
||||
compiler contain line numbers and file names referring to the source
|
||||
file before preprocessing, instead of after preprocessing.
|
||||
|
|
|
@ -12,20 +12,20 @@ This document is intended as a reference manual for the OCaml
|
|||
language. It lists the language constructs, and gives their precise
|
||||
syntax and informal semantics. It is by no means a tutorial
|
||||
introduction to the language: there is not a single example. A good
|
||||
working knowledge of Caml is assumed.
|
||||
working knowledge of OCaml is assumed.
|
||||
|
||||
No attempt has been made at mathematical rigor: words are employed
|
||||
with their intuitive meaning, without further definition. As a
|
||||
consequence, the typing rules have been left out, by lack of the
|
||||
mathematical framework required to express them, while they are
|
||||
definitely part of a full formal definition of the language.
|
||||
definitely part of a full formal definition of the language.
|
||||
|
||||
|
||||
\subsection*{Notations}
|
||||
|
||||
The syntax of the language is given in BNF-like notation. Terminal
|
||||
symbols are set in typewriter font (@'like' 'this'@).
|
||||
Non-terminal symbols are set in italic font (@@like@ @that@@).
|
||||
Non-terminal symbols are set in italic font (@@like@ @that@@).
|
||||
Square brackets @[\ldots]@ denote optional components. Curly brackets
|
||||
@{\ldots}@ denotes zero, one or several repetitions of the enclosed
|
||||
components. Curly bracket with a trailing plus sign @{{\ldots}}@
|
||||
|
|
|
@ -562,7 +562,7 @@ class ['observer, 'event] subject =
|
|||
\end{caml_example}
|
||||
The difficulty usually relies in defining instances of the pattern above
|
||||
by inheritance. This can be done in a natural and obvious manner in
|
||||
Ocaml, as shown on the following example manipulating windows.
|
||||
OCaml, as shown on the following example manipulating windows.
|
||||
\begin{caml_example}
|
||||
type event = Raise | Resize | Move;;
|
||||
let string_of_event = function
|
||||
|
@ -640,6 +640,6 @@ window#move 1; window#resize 2;;
|
|||
%
|
||||
|
||||
|
||||
% LocalWords: Caml objectexamples bsection init caml val int Oo succ incr ref
|
||||
% LocalWords: objectexamples bsection init caml val int Oo succ incr ref
|
||||
% LocalWords: typecheck leq bool cp eval sig struct ABSPOINT Abspoint iter neg
|
||||
% LocalWords: accu mem rec repr Euro euro ccp inlined ostring len concat OCaml
|
||||
|
|
|
@ -12,14 +12,14 @@ module system.
|
|||
\section{Basics}
|
||||
\pdfsection{Basics}
|
||||
|
||||
For this overview of Caml, we use the interactive system, which
|
||||
For this overview of OCaml, we use the interactive system, which
|
||||
is started by running "ocaml" from the Unix shell, or by launching the
|
||||
"OCamlwin.exe" application under Windows. This tutorial is presented
|
||||
as the transcript of a session with the interactive system:
|
||||
lines starting with "#" represent user input; the system responses are
|
||||
printed below, without a leading "#".
|
||||
|
||||
Under the interactive system, the user types Caml phrases, terminated
|
||||
Under the interactive system, the user types OCaml phrases, terminated
|
||||
by ";;", in response to the "#" prompt, and the system compiles them
|
||||
on the fly, executes them, and prints the outcome of evaluation.
|
||||
Phrases are either simple expressions, or "let" definitions of
|
||||
|
@ -30,7 +30,7 @@ let pi = 4.0 *. atan 1.0;;
|
|||
let square x = x *. x;;
|
||||
square(sin pi) +. square(cos pi);;
|
||||
\end{caml_example}
|
||||
The Caml system computes both the value and the type for
|
||||
The OCaml system computes both the value and the type for
|
||||
each phrase. Even function parameters need no explicit type declaration:
|
||||
the system infers their types from their usage in the
|
||||
function. Notice also that integers and floating-point numbers are
|
||||
|
@ -50,7 +50,7 @@ fib 10;;
|
|||
\section{Data types}
|
||||
\pdfsection{Data types}
|
||||
|
||||
In addition to integers and floating-point numbers, Caml offers the
|
||||
In addition to integers and floating-point numbers, OCaml offers the
|
||||
usual basic data types: booleans, characters, and character strings.
|
||||
\begin{caml_example}
|
||||
(1 < 2) = false;;
|
||||
|
@ -69,13 +69,13 @@ semicolon-separated elements, or built from the empty list "[]"
|
|||
let l = ["is"; "a"; "tale"; "told"; "etc."];;
|
||||
"Life" :: l;;
|
||||
\end{caml_example}
|
||||
As with all other Caml data structures, lists do not need to be
|
||||
As with all other OCaml data structures, lists do not need to be
|
||||
explicitly allocated and deallocated from memory: all memory
|
||||
management is entirely automatic in Caml. Similarly, there is no
|
||||
explicit handling of pointers: the Caml compiler silently introduces
|
||||
management is entirely automatic in OCaml. Similarly, there is no
|
||||
explicit handling of pointers: the OCaml compiler silently introduces
|
||||
pointers where necessary.
|
||||
|
||||
As with most Caml data structures, inspecting and destructuring lists
|
||||
As with most OCaml data structures, inspecting and destructuring lists
|
||||
is performed by pattern-matching. List patterns have the exact same
|
||||
shape as list expressions, with identifier representing unspecified
|
||||
parts of the list. As an example, here is insertion sort on a list:
|
||||
|
@ -96,7 +96,7 @@ The type inferred for "sort", "'a list -> 'a list", means that "sort"
|
|||
can actually apply to lists of any type, and returns a list of the
|
||||
same type. The type "'a" is a {\em type variable}, and stands for any
|
||||
given type. The reason why "sort" can apply to lists of any type is
|
||||
that the comparisons ("=", "<=", etc.) are {\em polymorphic} in Caml:
|
||||
that the comparisons ("=", "<=", etc.) are {\em polymorphic} in OCaml:
|
||||
they operate between any two values of the same type. This makes
|
||||
"sort" itself polymorphic over all list types.
|
||||
\begin{caml_example}
|
||||
|
@ -106,16 +106,16 @@ sort [3.14; 2.718];;
|
|||
|
||||
The "sort" function above does not modify its input list: it builds
|
||||
and returns a new list containing the same elements as the input list,
|
||||
in ascending order. There is actually no way in Caml to modify
|
||||
in ascending order. There is actually no way in OCaml to modify
|
||||
in-place a list once it is built: we say that lists are {\em immutable}
|
||||
data structures. Most Caml data structures are immutable, but a few
|
||||
data structures. Most OCaml data structures are immutable, but a few
|
||||
(most notably arrays) are {\em mutable}, meaning that they can be
|
||||
modified in-place at any time.
|
||||
|
||||
\section{Functions as values}
|
||||
\pdfsection{Functions as values}
|
||||
|
||||
Caml is a functional language: functions in the full mathematical
|
||||
OCaml is a functional language: functions in the full mathematical
|
||||
sense are supported and can be passed around freely just as any other
|
||||
piece of data. For instance, here is a "deriv" function that takes any
|
||||
float function as argument and returns an approximation of its
|
||||
|
@ -134,7 +134,7 @@ let cos2 = compose square cos;;
|
|||
Functions that take other functions as arguments are called
|
||||
``functionals'', or ``higher-order functions''. Functionals are
|
||||
especially useful to provide iterators or similar generic operations
|
||||
over a data structure. For instance, the standard Caml library
|
||||
over a data structure. For instance, the standard OCaml library
|
||||
provides a "List.map" functional that applies a given function to each
|
||||
element of a list, and returns the list of the results:
|
||||
\begin{caml_example}
|
||||
|
@ -163,7 +163,7 @@ let add_ratio r1 r2 =
|
|||
{num = r1.num * r2.denum + r2.num * r1.denum;
|
||||
denum = r1.denum * r2.denum};;
|
||||
add_ratio {num=1; denum=3} {num=2; denum=5};;
|
||||
\end{caml_example}
|
||||
\end{caml_example}
|
||||
|
||||
The declaration of a variant type lists all possible shapes for values
|
||||
of that type. Each case is identified by a name, called a constructor,
|
||||
|
@ -237,7 +237,7 @@ let rec insert x btree =
|
|||
\pdfsection{Imperative features}
|
||||
|
||||
Though all examples so far were written in purely applicative style,
|
||||
Caml is also equipped with full imperative features. This includes the
|
||||
OCaml is also equipped with full imperative features. This includes the
|
||||
usual "while" and "for" loops, as well as mutable data structures such
|
||||
as arrays. Arrays are either given in extension between "[|" and "|]"
|
||||
brackets, or allocated and initialized with the "Array.create"
|
||||
|
@ -265,7 +265,7 @@ translate mypoint 1.0 2.0;;
|
|||
mypoint;;
|
||||
\end{caml_example}
|
||||
|
||||
Caml has no built-in notion of variable -- identifiers whose current
|
||||
OCaml has no built-in notion of variable -- identifiers whose current
|
||||
value can be changed by assignment. (The "let" binding is not an
|
||||
assignment, it introduces a new identifier with a new scope.)
|
||||
However, the standard library provides references, which are mutable
|
||||
|
@ -321,7 +321,7 @@ g r;;
|
|||
\section{Exceptions}
|
||||
\pdfsection{Exceptions}
|
||||
|
||||
Caml provides exceptions for signalling and handling exceptional
|
||||
OCaml provides exceptions for signalling and handling exceptional
|
||||
conditions. Exceptions can also be used as a general-purpose non-local
|
||||
control structure. Exceptions are declared with the "exception"
|
||||
construct, and signalled with the "raise" operator. For instance, the
|
||||
|
@ -380,7 +380,7 @@ let temporarily_set_reference ref newval funct =
|
|||
\pdfsection{Symbolic processing of expressions}
|
||||
|
||||
We finish this introduction with a more complete example
|
||||
representative of the use of Caml for symbolic processing: formal
|
||||
representative of the use of OCaml for symbolic processing: formal
|
||||
manipulations of arithmetic expressions containing variables. The
|
||||
following variant type describes the expressions we shall manipulate:
|
||||
\begin{caml_example}
|
||||
|
@ -476,8 +476,8 @@ print_expr (deriv e "x"); print_newline();;
|
|||
\end{caml_example}
|
||||
|
||||
Parsing (transforming concrete syntax into abstract syntax) is usually
|
||||
more delicate. Caml offers several tools to help write parsers:
|
||||
on the one hand, Caml versions of the lexer generator Lex and the
|
||||
more delicate. OCaml offers several tools to help write parsers:
|
||||
on the one hand, OCaml versions of the lexer generator Lex and the
|
||||
parser generator Yacc (see chapter~\ref{c:ocamlyacc}), which handle
|
||||
LALR(1) languages using push-down automata; on the other hand, a
|
||||
predefined type of streams (of characters or tokens) and
|
||||
|
@ -560,15 +560,15 @@ read_expression "x-1";;
|
|||
Answer: the generic lexer provided by "Genlex" recognizes negative
|
||||
integer literals as one integer token. Hence, "x-1" is read as
|
||||
the token "Ident \"x\"" followed by the token "Int(-1)"; this sequence
|
||||
does not match any of the parser rules. On the other hand,
|
||||
does not match any of the parser rules. On the other hand,
|
||||
the second space in "x - 1" causes the lexer to return the three
|
||||
expected tokens: "Ident \"x\"", then "Kwd \"-\"", then "Int(1)".
|
||||
|
||||
\section{Standalone Caml programs}
|
||||
\pdfsection{Standalone Caml programs}
|
||||
\section{Standalone OCaml programs}
|
||||
\pdfsection{Standalone OCaml programs}
|
||||
|
||||
All examples given so far were executed under the interactive system.
|
||||
Caml code can also be compiled separately and executed
|
||||
OCaml code can also be compiled separately and executed
|
||||
non-interactively using the batch compilers "ocamlc" or "ocamlopt".
|
||||
The source code must be put in a file with extension ".ml". It
|
||||
consists of a sequence of phrases, which will be evaluated at runtime
|
||||
|
@ -588,7 +588,7 @@ let main () =
|
|||
main ();;
|
||||
\end{verbatim}
|
||||
"Sys.argv" is an array of strings containing the command-line
|
||||
parameters. "Sys.argv.(1)" is thus the first command-line parameter.
|
||||
parameters. "Sys.argv.(1)" is thus the first command-line parameter.
|
||||
The program above is compiled and executed with the following shell
|
||||
commands:
|
||||
\begin{verbatim}
|
||||
|
|
|
@ -40,7 +40,7 @@ let f ~x:x1 ~y:y1 = x1 - y1;;
|
|||
f ~x:3 ~y:2;;
|
||||
\end{caml_example}
|
||||
|
||||
Labels obey the same rules as other identifiers in Caml, that is you
|
||||
Labels obey the same rules as other identifiers in OCaml, that is you
|
||||
cannot use a reserved keyword (like "in" or "to") as label.
|
||||
|
||||
Formal parameters and arguments are matched according to their
|
||||
|
@ -340,7 +340,7 @@ List.map f [`On; `Off];;
|
|||
"[>`Off|`On] list" means that to match this list, you should at
|
||||
least be able to match "`Off" and "`On", without argument.
|
||||
"[<`On|`Off|`Number of int]" means that "f" may be applied to "`Off",
|
||||
"`On" (both without argument), or "`Number" $n$ where
|
||||
"`On" (both without argument), or "`Number" $n$ where
|
||||
$n$ is an integer.
|
||||
The ">" and "<" inside the variant type shows that they may still be
|
||||
refined, either by defining more tags or allowing less. As such they
|
||||
|
@ -353,7 +353,7 @@ When writing type annotations, one will most often describe fixed
|
|||
variant types, that is types that can be no longer refined. This is
|
||||
also the case for type abbreviations. Such types do not contain "<" or
|
||||
">", but just an enumeration of the tags and their associated types,
|
||||
just like in a normal datatype definition.
|
||||
just like in a normal datatype definition.
|
||||
\begin{caml_example}
|
||||
type 'a vlist = [`Nil | `Cons of 'a * 'a vlist];;
|
||||
let rec map f : 'a vlist -> 'b vlist = function
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
\chapter{Objects in Caml}
|
||||
\chapter{Objects in OCaml}
|
||||
\label{c:objectexamples}
|
||||
\pdfchapterfold{-15}{Tutorial: Objects in Caml}
|
||||
\pdfchapterfold{-15}{Tutorial: Objects in OCaml}
|
||||
|
||||
{\it (Chapter written by Jérôme Vouillon, Didier Rémy and Jacques Garrigue)}
|
||||
|
||||
|
@ -32,13 +32,13 @@ assume that similar keywords mean the same thing.
|
|||
\ref{ss:binary-methods} Binary methods \\
|
||||
\ref{ss:friends} Friends \\
|
||||
|
||||
%%\ref{s:advanced-examples} {\bf Advanced examples}
|
||||
%%\ref{s:advanced-examples} {\bf Advanced examples}
|
||||
%%
|
||||
%%\ref{ss:bank-accounts} An extended example of bank accounts \\
|
||||
%%\ref{ss:modules-as-classes} Simple modules as classes:
|
||||
%% \ref{module:string} Strings
|
||||
%% \ref{module:stack} Stacks
|
||||
%% \ref{module:hashtbl} Hash tables
|
||||
%% \ref{module:string} Strings
|
||||
%% \ref{module:stack} Stacks
|
||||
%% \ref{module:hashtbl} Hash tables
|
||||
%% \ref{module:set} Sets \\
|
||||
%%\ref{ss:subject-observer} The subject/observer pattern \\
|
||||
|
||||
|
@ -46,15 +46,15 @@ assume that similar keywords mean the same thing.
|
|||
|
||||
\section{Classes and objects}
|
||||
\pdfsection{Classes and objects}
|
||||
\label{ss:classes-and-objects}
|
||||
\label{ss:classes-and-objects}
|
||||
|
||||
The class "point" below defines one instance variable "x" and two methods
|
||||
"get_x" and "move". The initial value of the instance variable is "0".
|
||||
The variable "x" is declared mutable, so the method "move" can change
|
||||
its value.
|
||||
\begin{caml_example}
|
||||
\begin{caml_example}
|
||||
class point =
|
||||
object
|
||||
object
|
||||
val mutable x = 0
|
||||
method get_x = x
|
||||
method move d = x <- x + d
|
||||
|
@ -84,7 +84,7 @@ objects.
|
|||
\begin{caml_example}
|
||||
let x0 = ref 0;;
|
||||
class point =
|
||||
object
|
||||
object
|
||||
val mutable x = incr x0; !x0
|
||||
method get_x = x
|
||||
method move d = x <- x + d
|
||||
|
@ -95,9 +95,9 @@ new point#get_x;;
|
|||
|
||||
The class "point" can also be abstracted over the initial values of
|
||||
the "x" coordinate.
|
||||
\begin{caml_example}
|
||||
class point = fun x_init ->
|
||||
object
|
||||
\begin{caml_example}
|
||||
class point = fun x_init ->
|
||||
object
|
||||
val mutable x = x_init
|
||||
method get_x = x
|
||||
method move d = x <- x + d
|
||||
|
@ -107,7 +107,7 @@ Like in function definitions, the definition above can be
|
|||
abbreviated as:
|
||||
\begin{caml_example}
|
||||
class point x_init =
|
||||
object
|
||||
object
|
||||
val mutable x = x_init
|
||||
method get_x = x
|
||||
method move d = x <- x + d
|
||||
|
@ -121,22 +121,22 @@ let p = new point 7;;
|
|||
\end{caml_example}
|
||||
The parameter "x_init" is, of course, visible in the whole body of the
|
||||
definition, including methods. For instance, the method "get_offset"
|
||||
in the class below returns the position of the object relative to its
|
||||
in the class below returns the position of the object relative to its
|
||||
initial position.
|
||||
\begin{caml_example}
|
||||
class point x_init =
|
||||
object
|
||||
object
|
||||
val mutable x = x_init
|
||||
method get_x = x
|
||||
method get_offset = x - x_init
|
||||
method move d = x <- x + d
|
||||
method move d = x <- x + d
|
||||
end;;
|
||||
\end{caml_example}
|
||||
%Instance variables can only be used inside methods. For instance it would
|
||||
%not be possible to define
|
||||
%\begin{caml_example}
|
||||
%class point x_init =
|
||||
% object
|
||||
% object
|
||||
% val mutable x = x_init
|
||||
% val origin = x
|
||||
% method get_offset = x - origin
|
||||
|
@ -150,7 +150,7 @@ as follows:
|
|||
\begin{caml_example}
|
||||
class adjusted_point x_init =
|
||||
let origin = (x_init / 10) * 10 in
|
||||
object
|
||||
object
|
||||
val mutable x = origin
|
||||
method get_x = x
|
||||
method get_offset = x - origin
|
||||
|
@ -164,12 +164,12 @@ calling the definition of class "point" with the value of the
|
|||
\begin{caml_example}
|
||||
class adjusted_point x_init = point ((x_init / 10) * 10);;
|
||||
\end{caml_example}
|
||||
An alternative solution would have been to define the adjustment in
|
||||
An alternative solution would have been to define the adjustment in
|
||||
a special allocation function:
|
||||
\begin{caml_example}
|
||||
let new_adjusted_point x_init = new point ((x_init / 10) * 10);;
|
||||
\end{caml_example}
|
||||
However, the former pattern is generally more appropriate, since
|
||||
However, the former pattern is generally more appropriate, since
|
||||
the code for adjustment is part of the definition of the class and will be
|
||||
inherited.
|
||||
|
||||
|
@ -191,7 +191,7 @@ result is a single object rather than a class. All the constructs
|
|||
described in the rest of this section also apply to immediate objects.
|
||||
\begin{caml_example}
|
||||
let p =
|
||||
object
|
||||
object
|
||||
val mutable x = 0
|
||||
method get_x = x
|
||||
method move d = x <- x + d
|
||||
|
@ -236,7 +236,7 @@ p#print;;
|
|||
\end{caml_example}
|
||||
Dynamically, the variable "s" is bound at the invocation of a method. In
|
||||
particular, when the class "printable_point" is inherited, the variable
|
||||
"s" will be correctly bound to the object of the subclass.
|
||||
"s" will be correctly bound to the object of the subclass.
|
||||
|
||||
A common problem with self is that, as its type may be extended in
|
||||
subclasses, you cannot fix it in advance. Here is a simple example.
|
||||
|
@ -285,8 +285,8 @@ class printable_point x_init =
|
|||
let p = new printable_point 17;;
|
||||
\end{caml_example}
|
||||
Initializers cannot be overridden. On the contrary, all initializers are
|
||||
evaluated sequentially.
|
||||
Initializers are particularly useful to enforce invariants.
|
||||
evaluated sequentially.
|
||||
Initializers are particularly useful to enforce invariants.
|
||||
Another example can be seen in section \ref{ss:bank-accounts}.
|
||||
|
||||
|
||||
|
@ -312,7 +312,7 @@ class point x_init =
|
|||
inherit abstract_point x_init
|
||||
val mutable x = x_init
|
||||
method get_x = x
|
||||
method move d = x <- x + d
|
||||
method move d = x <- x + d
|
||||
end;;
|
||||
\end{caml_example}
|
||||
|
||||
|
@ -322,7 +322,7 @@ as with methods.
|
|||
class virtual abstract_point2 =
|
||||
object
|
||||
val mutable virtual x : int
|
||||
method move d = x <- x + d
|
||||
method move d = x <- x + d
|
||||
end;;
|
||||
class point2 x_init =
|
||||
object
|
||||
|
@ -338,7 +338,7 @@ class point2 x_init =
|
|||
|
||||
Private methods are methods that do not appear in object interfaces.
|
||||
They can only be invoked from other methods of the same object.
|
||||
\begin{caml_example}
|
||||
\begin{caml_example}
|
||||
class restricted_point x_init =
|
||||
object (self)
|
||||
val mutable x = x_init
|
||||
|
@ -358,11 +358,11 @@ objects of the same type, and there is no way at the type level to
|
|||
ensure that an object comes from a specific class. However a possible
|
||||
encoding of friend methods is given in section \ref{ss:friends}.
|
||||
|
||||
Private methods are inherited (they are by default visible in subclasses),
|
||||
Private methods are inherited (they are by default visible in subclasses),
|
||||
unless they are hidden by signature matching, as described below.
|
||||
|
||||
Private methods can be made public in a subclass.
|
||||
\begin{caml_example}
|
||||
Private methods can be made public in a subclass.
|
||||
\begin{caml_example}
|
||||
class point_again x =
|
||||
object (self)
|
||||
inherit restricted_point x
|
||||
|
@ -375,7 +375,7 @@ annotation, this makes the method public, keeping the original
|
|||
definition.
|
||||
|
||||
An alternative definition is
|
||||
\begin{caml_example}
|
||||
\begin{caml_example}
|
||||
class point_again x =
|
||||
object (self : < move : _; ..> )
|
||||
inherit restricted_point x
|
||||
|
@ -384,20 +384,20 @@ class point_again x =
|
|||
The constraint on self's type is requiring a public "move" method, and
|
||||
this is sufficient to override "private".
|
||||
|
||||
One could think that a private method should remain private in a subclass.
|
||||
One could think that a private method should remain private in a subclass.
|
||||
However, since the method is visible in a subclass, it is always possible
|
||||
to pick its code and define a method of the same name that runs that
|
||||
code, so yet another (heavier) solution would be:
|
||||
\begin{caml_example}
|
||||
\begin{caml_example}
|
||||
class point_again x =
|
||||
object
|
||||
inherit restricted_point x as super
|
||||
method move = super#move
|
||||
method move = super#move
|
||||
end;;
|
||||
\end{caml_example}
|
||||
|
||||
Of course, private methods can also be virtual. Then, the keywords must
|
||||
appear in this order "method private virtual".
|
||||
appear in this order "method private virtual".
|
||||
|
||||
\section{Class interfaces}
|
||||
\pdfsection{Class interfaces}
|
||||
|
@ -410,7 +410,7 @@ Class interfaces are inferred from class definitions. They may also
|
|||
be defined directly and used to restrict the type of a class. Like class
|
||||
declarations, they also define a new type abbreviation.
|
||||
\begin{caml_example}
|
||||
class type restricted_point_type =
|
||||
class type restricted_point_type =
|
||||
object
|
||||
method get_x : int
|
||||
method bump : unit
|
||||
|
@ -420,7 +420,7 @@ fun (x : restricted_point_type) -> x;;
|
|||
In addition to program documentation, class interfaces can be used to
|
||||
constrain the type of a class. Both concrete instance variables and concrete
|
||||
private methods can be hidden by a class type constraint. Public
|
||||
methods and virtual members, however, cannot.
|
||||
methods and virtual members, however, cannot.
|
||||
\begin{caml_example}
|
||||
class restricted_point' x = (restricted_point x : restricted_point_type);;
|
||||
\end{caml_example}
|
||||
|
@ -429,16 +429,16 @@ Or, equivalently:
|
|||
class restricted_point' = (restricted_point : int -> restricted_point_type);;
|
||||
\end{caml_example}
|
||||
The interface of a class can also be specified in a module
|
||||
signature, and used to restrict the inferred signature of a module.
|
||||
signature, and used to restrict the inferred signature of a module.
|
||||
\begin{caml_example}
|
||||
module type POINT = sig
|
||||
module type POINT = sig
|
||||
class restricted_point' : int ->
|
||||
object
|
||||
object
|
||||
method get_x : int
|
||||
method bump : unit
|
||||
end
|
||||
end
|
||||
end;;
|
||||
module Point : POINT = struct
|
||||
module Point : POINT = struct
|
||||
class restricted_point' = restricted_point
|
||||
end;;
|
||||
\end{caml_example}
|
||||
|
@ -453,7 +453,7 @@ variables and all methods of class "point", plus a new instance
|
|||
variable "c" and a new method "color".
|
||||
\begin{caml_example}
|
||||
class colored_point x (c : string) =
|
||||
object
|
||||
object
|
||||
inherit point x
|
||||
val c = c
|
||||
method color = c
|
||||
|
@ -488,7 +488,7 @@ ancestor. Below, "super" is bound to the ancestor "printable_point".
|
|||
The name "super" is a pseudo value identifier that can only be used to
|
||||
invoke a super-class method, as in "super#print".
|
||||
\begin{caml_example}
|
||||
class printable_colored_point y c =
|
||||
class printable_colored_point y c =
|
||||
object (self)
|
||||
val c = c
|
||||
method color = c
|
||||
|
@ -516,20 +516,20 @@ Reference cells can be implemented as objects.
|
|||
The naive definition fails to typecheck:
|
||||
\begin{caml_example}
|
||||
class ref x_init =
|
||||
object
|
||||
object
|
||||
val mutable x = x_init
|
||||
method get = x
|
||||
method set y = x <- y
|
||||
end;;
|
||||
\end{caml_example}
|
||||
The reason is that at least one of the methods has a polymorphic type
|
||||
(here, the type of the value stored in the reference cell), thus
|
||||
(here, the type of the value stored in the reference cell), thus
|
||||
either the class should be parametric, or the method type should be
|
||||
constrained to a monomorphic type. A monomorphic instance of the class could
|
||||
be defined by:
|
||||
\begin{caml_example}
|
||||
class ref (x_init:int) =
|
||||
object
|
||||
object
|
||||
val mutable x = x_init
|
||||
method get = x
|
||||
method set y = x <- y
|
||||
|
@ -539,7 +539,7 @@ Note that since immediate objects do not define a class type, they have
|
|||
no such restriction.
|
||||
\begin{caml_example}
|
||||
let new_ref x_init =
|
||||
object
|
||||
object
|
||||
val mutable x = x_init
|
||||
method get = x
|
||||
method set y = x <- y
|
||||
|
@ -550,8 +550,8 @@ list the type parameters in its declaration. Class type parameters are
|
|||
always listed between "[" and "]". The type parameters must also be
|
||||
bound somewhere in the class body by a type constraint.
|
||||
\begin{caml_example}
|
||||
class ['a] ref x_init =
|
||||
object
|
||||
class ['a] ref x_init =
|
||||
object
|
||||
val mutable x = (x_init : 'a)
|
||||
method get = x
|
||||
method set y = x <- y
|
||||
|
@ -560,9 +560,9 @@ let r = new ref 1 in r#set 2; (r#get);;
|
|||
\end{caml_example}
|
||||
The type parameter in the declaration may actually be constrained in the
|
||||
body of the class definition. In the class type, the actual value of
|
||||
the type parameter is displayed in the "constraint" clause.
|
||||
the type parameter is displayed in the "constraint" clause.
|
||||
\begin{caml_example}
|
||||
class ['a] ref_succ (x_init:'a) =
|
||||
class ['a] ref_succ (x_init:'a) =
|
||||
object
|
||||
val mutable x = x_init + 1
|
||||
method get = x
|
||||
|
@ -571,11 +571,11 @@ class ['a] ref_succ (x_init:'a) =
|
|||
\end{caml_example}
|
||||
Let us consider a more complex example: define a circle, whose center
|
||||
may be any kind of point. We put an additional type
|
||||
constraint in method "move", since no free variables must remain
|
||||
constraint in method "move", since no free variables must remain
|
||||
unaccounted for by the class type parameters.
|
||||
\begin{caml_example}
|
||||
class ['a] circle (c : 'a) =
|
||||
object
|
||||
object
|
||||
val mutable center = c
|
||||
method center = center
|
||||
method set_center c = center <- c
|
||||
|
@ -593,7 +593,7 @@ constraints on its argument, as we now expect "center" to have a
|
|||
method "get_x".
|
||||
\begin{caml_example}
|
||||
class ['a] circle (c : 'a) =
|
||||
object
|
||||
object
|
||||
constraint 'a = #point
|
||||
val mutable center = c
|
||||
method center = center
|
||||
|
@ -605,7 +605,7 @@ The class "colored_circle" is a specialized version of class
|
|||
"circle" that requires the type of the center to unify with
|
||||
"#colored_point", and adds a method "color". Note that when specializing a
|
||||
parameterized class, the instance of type parameter must always be
|
||||
explicitly given. It is again written between "[" and "]".
|
||||
explicitly given. It is again written between "[" and "]".
|
||||
\begin{caml_example}
|
||||
class ['a] colored_circle c =
|
||||
object
|
||||
|
@ -762,9 +762,9 @@ let colored_point_to_point cp = (cp : colored_point :> point);;
|
|||
let p = new point 3 and q = new colored_point 4 "blue";;
|
||||
let l = [p; (colored_point_to_point q)];;
|
||||
\end{caml_example}
|
||||
An object of type "t" can be seen as an object of type "t'"
|
||||
An object of type "t" can be seen as an object of type "t'"
|
||||
only if "t" is a subtype of "t'". For instance, a point cannot be
|
||||
seen as a colored point.
|
||||
seen as a colored point.
|
||||
\begin{caml_example}
|
||||
(p : point :> colored_point);;
|
||||
\end{caml_example}
|
||||
|
@ -772,7 +772,7 @@ Indeed, narrowing coercions without runtime checks would be unsafe.
|
|||
Runtime type checks might raise exceptions, and they would require
|
||||
the presence of type information at runtime, which is not the case in
|
||||
the OCaml system.
|
||||
For these reasons, there is no such operation available in the language.
|
||||
For these reasons, there is no such operation available in the language.
|
||||
|
||||
Be aware that subtyping and inheritance are not related. Inheritance is a
|
||||
syntactic relation between classes while subtyping is a semantic relation
|
||||
|
@ -791,31 +791,31 @@ define:
|
|||
\begin{caml_example}
|
||||
let to_point cp = (cp :> point);;
|
||||
\end{caml_example}
|
||||
In this case, the function "colored_point_to_point" is an instance of the
|
||||
In this case, the function "colored_point_to_point" is an instance of the
|
||||
function "to_point". This is not always true, however. The fully
|
||||
explicit coercion is more precise and is sometimes unavoidable.
|
||||
explicit coercion is more precise and is sometimes unavoidable.
|
||||
Consider, for example, the following class:
|
||||
\begin{caml_example}
|
||||
class c0 = object method m = {< >} method n = 0 end;;
|
||||
\end{caml_example}
|
||||
The object type "c0" is an abbreviation for "<m : 'a; n : int> as 'a".
|
||||
The object type "c0" is an abbreviation for "<m : 'a; n : int> as 'a".
|
||||
Consider now the type declaration:
|
||||
\begin{caml_example}
|
||||
class type c1 = object method m : c1 end;;
|
||||
\end{caml_example}
|
||||
The object type "c1" is an abbreviation for the type "<m : 'a> as 'a".
|
||||
The object type "c1" is an abbreviation for the type "<m : 'a> as 'a".
|
||||
The coercion from an object of type "c0" to an object of type "c1" is
|
||||
correct:
|
||||
correct:
|
||||
\begin{caml_example}
|
||||
fun (x:c0) -> (x : c0 :> c1);;
|
||||
\end{caml_example}
|
||||
%%% FIXME come up with a better example.
|
||||
% However, the domain of the coercion cannot be omitted here:
|
||||
% However, the domain of the coercion cannot be omitted here:
|
||||
% \begin{caml_example}
|
||||
% fun (x:c0) -> (x :> c1);;
|
||||
% \end{caml_example}
|
||||
However, the domain of the coercion cannot always be omitted.
|
||||
In that case, the solution is to use the explicit form.
|
||||
In that case, the solution is to use the explicit form.
|
||||
%
|
||||
Sometimes, a change in the class-type definition can also solve the problem
|
||||
\begin{caml_example}
|
||||
|
@ -830,7 +830,7 @@ than the object type, is used to derive the coercion function. This
|
|||
allows to leave the domain implicit in most cases when coercing form a
|
||||
subclass to its superclass.
|
||||
%
|
||||
The type of a coercion can always be seen as below:
|
||||
The type of a coercion can always be seen as below:
|
||||
\begin{caml_example}
|
||||
let to_c1 x = (x :> c1);;
|
||||
let to_c2 x = (x :> c2);;
|
||||
|
@ -859,7 +859,7 @@ parameterless classes the coercion "(_ :> c)" is always more general than
|
|||
A common problem may occur when one tries to define a coercion to a
|
||||
class "c" while defining class "c". The problem is due to the type
|
||||
abbreviation not being completely defined yet, and so its subtypes are not
|
||||
clearly known. Then, a coercion "(_ :> c)" or "(_ : #c :> c)" is taken to be
|
||||
clearly known. Then, a coercion "(_ :> c)" or "(_ : #c :> c)" is taken to be
|
||||
the identity function, as in
|
||||
\begin{caml_example}
|
||||
function x -> (x :> 'a);;
|
||||
|
@ -932,7 +932,7 @@ One could think of defining the type abbreviation directly:
|
|||
type c' = <m : int>;;
|
||||
\end{caml_example*}
|
||||
However, the abbreviation "#c'" cannot be defined directly in a similar way.
|
||||
It can only be defined by a class or a class-type definition.
|
||||
It can only be defined by a class or a class-type definition.
|
||||
This is because "#" sharp abbreviations carry an implicit anonymous
|
||||
variable ".." that cannot be explicitly named.
|
||||
The closer you get to it is:
|
||||
|
@ -951,7 +951,7 @@ on the instance variables. The construct "{< ... >}" returns a copy of
|
|||
some instance variables.
|
||||
\begin{caml_example}
|
||||
class functional_point y =
|
||||
object
|
||||
object
|
||||
val x = y
|
||||
method get_x = x
|
||||
method move d = {< x = x + d >}
|
||||
|
@ -966,10 +966,10 @@ be seen in the class type of "functional_point": the type of self is "'a"
|
|||
and "'a" appears inside the type of the method "move".
|
||||
|
||||
The above definition of "functional_point" is not equivalent
|
||||
to the following:
|
||||
to the following:
|
||||
\begin{caml_example}
|
||||
class bad_functional_point y =
|
||||
object
|
||||
object
|
||||
val x = y
|
||||
method get_x = x
|
||||
method move d = new bad_functional_point (x+d)
|
||||
|
@ -990,13 +990,13 @@ as illustrated in section \ref{module:string}.
|
|||
\label{ss:cloning-objects}
|
||||
|
||||
Objects can also be cloned, whether they are functional or imperative.
|
||||
The library function "Oo.copy" makes a shallow copy of an object. That is,
|
||||
it returns an object that is equal to the previous one. The
|
||||
The library function "Oo.copy" makes a shallow copy of an object. That is,
|
||||
it returns an object that is equal to the previous one. The
|
||||
instance variables have been copied but their contents are shared.
|
||||
Assigning a new value to an instance variable of the copy (using a method
|
||||
call) will not affect instance variables of the original, and conversely.
|
||||
A deeper assignment (for example if the instance variable if a reference cell)
|
||||
will of course affect both the original and the copy.
|
||||
call) will not affect instance variables of the original, and conversely.
|
||||
A deeper assignment (for example if the instance variable if a reference cell)
|
||||
will of course affect both the original and the copy.
|
||||
|
||||
The type of "Oo.copy" is the following:
|
||||
\begin{caml_example}
|
||||
|
@ -1029,7 +1029,7 @@ ordering relationship between two objects is fixed once for all after the
|
|||
two objects have been created and it is not affected by mutation of fields.
|
||||
|
||||
Cloning and override have a non empty intersection.
|
||||
They are interchangeable when used within an object and without
|
||||
They are interchangeable when used within an object and without
|
||||
overriding any field:
|
||||
\begin{caml_example}
|
||||
class copy =
|
||||
|
@ -1041,32 +1041,32 @@ class copy =
|
|||
method copy = Oo.copy self
|
||||
end;;
|
||||
\end{caml_example}
|
||||
Only the override can be used to actually override fields, and
|
||||
only the "Oo.copy" primitive can be used externally.
|
||||
Only the override can be used to actually override fields, and
|
||||
only the "Oo.copy" primitive can be used externally.
|
||||
|
||||
Cloning can also be used to provide facilities for saving and
|
||||
restoring the state of objects.
|
||||
\begin{caml_example}
|
||||
class backup =
|
||||
class backup =
|
||||
object (self : 'mytype)
|
||||
val mutable copy = None
|
||||
method save = copy <- Some {< copy = None >}
|
||||
method restore = match copy with Some x -> x | None -> self
|
||||
end;;
|
||||
\end{caml_example}
|
||||
The above definition will only backup one level.
|
||||
The above definition will only backup one level.
|
||||
The backup facility can be added to any class using multiple inheritance.
|
||||
\begin{caml_example}
|
||||
class ['a] backup_ref x = object inherit ['a] ref x inherit backup end;;
|
||||
let rec get p n = if n = 0 then p # get else get (p # restore) (n-1);;
|
||||
let p = new backup_ref 0 in
|
||||
p # save; p # set 1; p # save; p # set 2;
|
||||
p # save; p # set 1; p # save; p # set 2;
|
||||
[get p 0; get p 1; get p 2; get p 3; get p 4];;
|
||||
\end{caml_example}
|
||||
A variant of backup could retain all copies. (We then add a method clear to
|
||||
manually erase all copies.)
|
||||
\begin{caml_example}
|
||||
class backup =
|
||||
class backup =
|
||||
object (self : 'mytype)
|
||||
val mutable copy = None
|
||||
method save = copy <- Some {< >}
|
||||
|
@ -1077,7 +1077,7 @@ class backup =
|
|||
\begin{caml_example}
|
||||
class ['a] backup_ref x = object inherit ['a] ref x inherit backup end;;
|
||||
let p = new backup_ref 0 in
|
||||
p # save; p # set 1; p # save; p # set 2;
|
||||
p # save; p # set 1; p # save; p # set 2;
|
||||
[get p 0; get p 1; get p 2; get p 3; get p 4];;
|
||||
\end{caml_example}
|
||||
|
||||
|
@ -1091,7 +1091,7 @@ Recursive classes can be used to define objects whose types are
|
|||
mutually recursive.
|
||||
\begin{caml_example}
|
||||
class window =
|
||||
object
|
||||
object
|
||||
val mutable top_widget = (None : widget option)
|
||||
method top_widget = top_widget
|
||||
end
|
||||
|
@ -1101,8 +1101,8 @@ and widget (w : window) =
|
|||
method window = window
|
||||
end;;
|
||||
\end{caml_example}
|
||||
Although their types are mutually recursive, the classes "widget" and
|
||||
"window" are themselves independent.
|
||||
Although their types are mutually recursive, the classes "widget" and
|
||||
"window" are themselves independent.
|
||||
|
||||
|
||||
\section{Binary methods}
|
||||
|
@ -1116,12 +1116,12 @@ is bound to the type of self. Therefore, "#comparable" expands to "<
|
|||
leq : 'a -> bool; .. > as 'a". We see here that the binder "as" also
|
||||
allows to write recursive types.
|
||||
\begin{caml_example}
|
||||
class virtual comparable =
|
||||
class virtual comparable =
|
||||
object (_ : 'a)
|
||||
method virtual leq : 'a -> bool
|
||||
end;;
|
||||
\end{caml_example}
|
||||
We then define a subclass "money" of "comparable". The class money
|
||||
We then define a subclass "money" of "comparable". The class money
|
||||
simply wraps floats as comparable objects. We will extend it below with
|
||||
more operations. There is a type constraint on the class parameter "x"
|
||||
as the primitive "<=" is a polymorphic comparison function in
|
||||
|
@ -1149,7 +1149,7 @@ call method "leq" on "m" with an argument that does not have a method
|
|||
Similarly, the type "money2" below is not a subtype of type "money".
|
||||
\begin{caml_example}
|
||||
class money2 x =
|
||||
object
|
||||
object
|
||||
inherit money x
|
||||
method times k = {< repr = k *. repr >}
|
||||
end;;
|
||||
|
@ -1175,11 +1175,11 @@ or "money2".
|
|||
More examples of binary methods can be found in sections
|
||||
\ref{module:string} and \ref{module:set}.
|
||||
|
||||
Notice the use of functional update for method "times".
|
||||
Notice the use of functional update for method "times".
|
||||
Writing "new money2 (k *. repr)" instead of "{< repr = k *. repr >}"
|
||||
would not behave well with inheritance: in a subclass "money3" of "money2"
|
||||
the "times" method would return an object of class "money2" but not of class
|
||||
"money3" as would be expected.
|
||||
"money3" as would be expected.
|
||||
|
||||
The class "money" could naturally carry another binary method. Here is a
|
||||
direct definition:
|
||||
|
@ -1220,20 +1220,20 @@ To make it available to other objects of the same class, we are forced to
|
|||
make it available to the whole world. However we can easily restrict the
|
||||
visibility of the representation using the module system.
|
||||
\begin{caml_example*}
|
||||
module type MONEY =
|
||||
sig
|
||||
module type MONEY =
|
||||
sig
|
||||
type t
|
||||
class c : float ->
|
||||
class c : float ->
|
||||
object ('a)
|
||||
val repr : t
|
||||
method value : t
|
||||
method print : unit
|
||||
method times : float -> 'a
|
||||
method leq : 'a -> bool
|
||||
method plus : 'a -> 'a
|
||||
method plus : 'a -> 'a
|
||||
end
|
||||
end;;
|
||||
module Euro : MONEY =
|
||||
module Euro : MONEY =
|
||||
struct
|
||||
type t = float
|
||||
class c x =
|
||||
|
@ -1258,6 +1258,6 @@ representation abstract outside of the module.
|
|||
|
||||
|
||||
% LocalWords: typecheck monomorphic uncaptured Subtyping subtyping leq repr Oo
|
||||
% LocalWords: val sig bool Euro struct Caml Vouillon Didier int ref incr init
|
||||
% LocalWords: val sig bool Euro struct OCaml Vouillon Didier int ref incr init
|
||||
% LocalWords: succ mytype rec
|
||||
|
||||
|
|
Loading…
Reference in New Issue