Présentation de la partie I
La première partie de cet ouvrage est une introduction complète au
noyau du langage Objective CAML, en particulier le
mécanisme d'évaluation d'une expression, le typage statique et le
modèle mémoire des données.
Une expression est la description d'un calcul. L'évaluation d'une expression retourne
à la fin du calcul une valeur. L'exécution d'un programme en Objective CAML correspond au calcul
d'une expression.
Les fonctions, les structures de
contrôle de l'exécution d'un programme, telles les conditionnelles ou
les boucles, sont elles aussi des expressions.
Le typage statique garantit que le calcul d'une expression ne pourra
pas déclencher une erreur de type à l'exécution. Dans les faits,
l'application d'une fonction à des arguments (ou paramètres effectifs) n'est acceptée que
s'ils ont tous un type compatible avec les paramètres
formels indiqués dans la définition de la fonction. Le langage Objective CAML possède en outre une
inférence de types : le compilateur détermine automatiquement le type
le plus général d'une expression.
Enfin la connaissance minimale de la représentation des données est indispensable au
programmeur pour maîtriser les effets des modifications physiques sur les données.
Plan
Le chapitre 2 contient une présentation complète de la partie
purement fonctionnelle du langage et des contraintes dues au typage
statique. La notion de calcul d'expression y est longuement
illustrée. Les structures de contrôle suivantes sont détaillées : la
conditionnelle, l'application et le filtrage de motif. Les différences
entre type et domaine d'une fonction sont discutées afin d'introduire
le mécanisme d'exceptions. Ce trait du langage sort du cadre fonctionnel
et permet la gestion de ruptures
de calcul.
Le chapitre 3 expose le style impératif. Les
constructions y sont plus proches des langages classiques. Les
structures de contrôle associées comme la séquence et l'itération y
sont présentées ainsi que les structures de données physiquement modifiables.
L'interaction entre modifications physiques et partage de
données est alors détaillée. L'inférence de types y est précisée en tenant compte de ces
nouvelles constructions.
Le chapitre 4 compare les deux styles précédents
et surtout présente différents styles mixtes. Ce mélange permettra en
particulier de construire des structures de données paresseuses, y
compris physiquement modifiables.
Le chapitre 5 montre l'utilisation de la bibliothèque
Graphics incluse dans la distribution du langage. Les
notions de base de la programmation graphique y sont exposées et
immédiatement mises en oeuvre. Il en est de même pour la
construction d'interfaces graphiques grâce à la gestion d'événements
minimale fournie par cette bibliothèque.
Ces quatre premiers chapitres sont illustrés par un exemple complet,
l'implantation
d'une calculatrice, qui évolue de chapitre en
chapitre.
Le chapitre 6 présente trois
applications complètes : une petite base de données, l'interprète
d'un mini-BASIC et le jeu Démineur. Les deux premiers exemples sont
construits principalement dans un style fonctionnel, alors que le
troisième l'est dans un style impératif.
Rudiments de syntaxe
Avant de commencer nous indiquons les premiers éléments de syntaxe du
langage. Un programme est une suite de phrases du langage. Une phrase
est un élément de syntaxe complet directement exécutable (expression, déclaration).
La fin
d'une phrase se termine par un double point-virgule (;;).
On distingue trois types de déclarations qui sont repérées par un mot
clé différent :
déclaration de valeur |
: |
let |
déclaration d'exception |
: |
exception |
déclaration de type |
: |
type |
Tous les exemples donnés dans cette partie sont à écrire au niveau
de la boucle d'interaction du langage.
Voici un premier (petit) programme Objective CAML, entré sous la boucle
d'interaction, dont l'invite est le caractère dièse (#
),
où sont définies une fonction fact
calculant la factorielle d'un nombre, et son application à l'entier
8
.
# let
rec
fact
n
=
if
n
<
2
then
1
else
n
*
fact(n-
1
)
;;
val fact : int -> int = <fun>
# fact
8
;;
- : int = 40320
Ce programme comprend deux phrases. La première est la
déclaration d'une valeur fonctionnelle et la seconde est une
expression. On s'aperçoit que la boucle d'interaction affiche
trois informations qui sont : le nom de la déclaration, ou le
caractère moins (-
) dans le cas d'une expression ; le type inféré ;
et la valeur retournée. Dans le cas d'une valeur fonctionnelle, le
système affiche <fun>
.
L'exemple suivant montre la manipulation de fonctions comme valeurs du
langage. On y définit tout d'abord la fonction succ qui
calcule le successeur d'un entier, puis la fonction compose
qui compose deux fonctions. Celle-ci sera appliquée à fact
et 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
Ce dernier appel effectue le calcul fact(succ
8
) et retourne
le résultat escompté. Notons que les fonctions fact et
succ sont passées en paramètres à compose au
même titre que l'entier 8
.