Description du langage
Objective CAML est un langage fonctionnel :
il manipule les fonctions comme étant des valeurs du
langage. Celles-ci peuvent être utilisées en tant que paramètres
d'autres fonctions ou être retournées comme résultat d'un appel de
fonction.
Objective CAML est typé statiquement :
la vérification de la compatibilité entre les types des paramètres
formels et des paramètres d'appel est effectuée au moment de la
compilation du programme. Dès lors, il n'est pas nécessaire de
faire ces vérifications durant l'exécution du programme ce qui
accroît son efficacité. En outre, la vérification de type permet
d'éliminer la plupart des erreurs introduites par maladresse ou
étourderie et contribue à la sûreté de l'exécution.
Objective CAML est polymorphe paramétrique :
une fonction qui n'explore pas la totalité de la structure d'un de ses
arguments accepte que celui-ci ait un type non entièrement
déterminé. Ce paramètre est alors dit polymorphe. Cette
particularité permet de développer un code générique
utilisable pour des structures de données différentes tant que
la représentation exacte de cette structure n'a pas besoin d'être
connue par le code en question. L'algorithme de typage est à
même de faire cette distinction.
Objective CAML possède une inférence de types :
le programmeur n'a besoin de donner aucune information de type à
l'intérieur de son programme. Le langage se charge seul de déduire
du code le type le plus général des expressions et des
déclarations qui y figurent. Cette inférence est effectuée
conjointement à la vérification, lors de la compilation du programme.
Objective CAML est muni d'un mécanisme d'exceptions :
il est possible de rompre l'exécution normale d'un programme à un
endroit et de la reprendre à un autre endroit du programme prévu à
cet effet. Ce mécanisme permet de gérer les situations
exceptionnelles, mais il peut aussi être adopté comme style de
programmation.
Objective CAML possède des traits impératifs :
les entrées-sorties, les modifications physiques de valeurs et les
structures de contrôle itératives sont possibles sans avoir recours
aux traits de la programmation fonctionnelle. Le mélange des deux
styles est bien entendu accepté et offre une grande souplesse de
développement ainsi que la possibilité de définir des structures
de données nouvelles.
Objective CAML exécute des processus légers (threads) :
les principaux outils de création, de synchronisation pour la
gestion de la mémoire partagée et de communication entre différents
processus légers sont prédéfinis.
Objective CAML communique sur le réseau Internet :
les bases nécessaires à l'ouverture de canaux de communication
entre différentes machines sont prédéfinies et permettent la
réalisation d'applications suivant l'architecture client-serveur.
Objective CAML dispose de nombreuses bibliothèques :
structures de données classiques, entrées-sorties, interfaçage avec
les ressources du système, analyses lexicale et syntaxique, calcul sur
les grands nombres, valeurs persistantes, etc.
Objective CAML dispose d'un environnement de programmation :
incluant une boucle d'interaction, une trace de l'exécution, un
calcul des dépendances et une analyse de performance.
Objective CAML interagit avec le langage C :
via l'appel de fonctions C à partir d'un programme Objective CAML et
réciproquement, permettant ainsi l'accès aux nombreuses bibliothèques
C.
Objective CAML dispose de trois modes d'exécution :
interactif par le biais d'une boucle d'interaction, compilation vers
du code-octet interprété par une machine virtuelle, compilation
vers du code machine. Le programmeur peut donc choisir entre
souplesse de développement, portabilité du code objet sur différentes
architectures ou performance sur une architecture donnée.
Structuration d'un programme
La réalisation d'applications importantes oblige le
programmeur ou l'équipe de développement à se poser des
questions d'organisation et de structuration. En Objective CAML, on
dispose de deux modèles dont les avantages et les particularités
sont distincts.
Modèle des modules paramétrés :
les données et les traitements sont regroupés au sein d'une même
entité à deux facettes : d'un côté le code proprement dit, de
l'autre son interface. La communication entre modules s'effectue via
leur interface. La description d'un type peut être masquée en
n'apparaissant pas dans l'interface du module. Ces types de données
abstraits facilitent les modifications d'implantation à l'intérieur
d'un module sans affecter les autres modules qui s'en servent. De
plus, les modules peuvent être paramétrés par d'autres modules
augmentant ainsi leur réutilisabilité.
Modèle objet :
les descriptions des traitements et des données sont regroupées dans des entités
appelées
classes; un objet est une instance (valeur) d'une classe.
La communication entre objets est réalisée par
<<envoi de message>>, l'objet receveur détermine à l'exécution (liaison retardée)
le traitement correspondant
au message. En cela, la programmation objet est <<dirigée>> par les
données. La structuration d'un programme provient des relations entre classes,
en particulier l'héritage permet de définir une classe par extension d'une autre.
Ce modèle accepte les classes concrètes,
abstraites et paramétriques.
De plus, il introduit le polymorphisme d'inclusion en définissant la relation
de sous-typage entre classes.
Le choix entre ces deux modèles permet une grande souplesse dans
l'organisation logique d'une application et facilite sa maintenance et
son évolution. Il y a dualité entre ces deux modèles. On ne peut
pas augmenter les composants d'un type dans un module (pas
d'extensibilité des données), mais on peut ajouter de nouveaux
traitements (extensibilité des traitements) sur ces données. En objet,
on peut ajouter des sous-classes à une classe (extensibilité des
données) pour traiter des nouveaux cas, mais on ne peut pas ajouter de
nouveaux traitements visibles de la classe ancêtre (pas
d'extensibilité des traitements). Néanmoins la combinaison des deux
offre de nouvelles extensibilités pour les traitements et les données.
Sûreté et efficacité de l'exécution
Objective CAML possède une excellente sûreté d'exécution de ses programmes
sans sacrifier pour autant leur efficacité. Fondamentalement le typage
statique est une garantie d'absence d'erreur de type à l'exécution
et apporte une information statique utile pour le compilateur sans
grever les performances par des tests dynamiques de types et cela y
compris pour l'extension objet. De même le récupérateur automatique de
mémoire est un gage de bonne sûreté. Celui d'Objective CAML est, de plus,
particulièrement efficace. Le mécanisme d'exceptions garantit que le
programme ne se retrouvera pas dans un état incohérent suite à une
division par zéro ou un accès en dehors des bornes d'un tableau.