Presenting part I
The first part of this book is a complete introduction to the core of the
Objective CAML language, in particular the expression evaluation mechanism,
static typing and the data memory model.
An expression is the description of a computation. Evaluation of an
expression returns a value at the end of the computation. The execution of
an Objective CAML program corresponds to the computation of an expression.
Functions, program execution control structures, even conditions or loops,
are themselves also expressions.
Static typing guarantees that the computation of an expression cannot cause
a run-time type error. In fact, application of a function to some
arguments (or actual parameters) isn't accepted unless they all have types
compatible with the formal parameters indicated in the definition of the
function. Furthermore, the Objective CAML language has type infererence: the
compiler automatically determines the most general type of an expression.
Finally a minimal knowledge of the representation of data is indispensable
to the programmer in order to master the effects of physical modifications
to the data.
Outline
Chapter 2 contains a complete presentation of the purely
functional part of the language and the constraints due to static typing.
The notion of expression evaluation is illustrated there at length. The
following control structures are detailed: conditional, function
application and pattern matching. The differences between the type and the
domain of a function are discussed in order to introduce the exception
mechanism. This feature of the language goes beyond the functional context
and allows management of computational breakdowns.
Chapter 3 exhibits the imperative style. The constructions
there are closer to classic languages. Associative control structures such
as sequence and iteration are presented there, as well as mutable data
structures. The interaction between physical modifications and sharing of
data is then detailed. Type inference is described there in the context of
these new constructions.
Chapter 4 compares the two preceding styles and
especially presents different mixed styles. This mixture supports in
particular the construction of lazy data structures, including mutable
ones.
Chapter 5 demonstrates the use of the Graphics
library included in the language distribution. The basic notions of
graphics programming are exhibited there and immediately put into practice.
There's even something about GUI construction thanks to the minimal event
control provided by this library.
These first four chapters are illustrated by a complete example, the
implementation
of a calculator, which evolves from chapter to chapter.
Chapter 6 presents three complete
applications: a little database, a mini-BASIC interpreter and the game
Minesweeper. The first two examples are constructed mainly in a functional
style, while the third is done in an imperative style.
The rudiments of syntax
Before beginning we indicate the first elements of the syntax of the
language. A program is a sequence of phrases in the language. A phrase is
a complete, directly executable syntactic element (an expression, a
declaration). A phrase is terminated with a double semi-colon
(;;). There are three different types of declarations which are
each marked with a different keyword:
value declaration |
: |
let |
exception declaration |
: |
exception |
type declaration |
: |
type |
All the examples given in this part are to be input into the interactive
toplevel of the language.
Here's a first (little) Objective CAML program, to be entered into the toplevel,
whose prompt is the pound character (#
),
in which a function fact
computing the factorial of a natural number, and
its application to a natural number 8
, are defined.
# let
rec
fact
n
=
if
n
<
2
then
1
else
n
*
fact(n-
1
)
;;
val fact : int -> int = <fun>
# fact
8
;;
- : int = 40320
This program consists of two phrases. The first is the declaration of
a function value and the second is an expression. One sees that the
toplevel prints out three pieces of information which are: the name being
declared, or a dash (-
) in the case of an expression; the inferred
type; and the return value. In the case of a function value, the system
prints <fun>
.
The following example demonstrates the manipulation of functions as values
in the language. There we first of all define the function succ
which calculates the successor of an integer, then the function
compose which composes two functions. The latter will be
applied to fact and succ.
# let
succ
x
=
x+
1
;;
val succ : int -> int = <fun>
# let
compose
f
g
x
=
f(g
x)
;;
val compose : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>
# compose
fact
succ
8
;;
- : int = 362880
This last call carries out the computation fact(succ
8
) and
returns the expected result. Let us note that the functions
fact and succ are passed as parameters to compose in
the same way as the natural number 8
.