Une présentation rapide du langage Ada
Le langage que nous utilisons dans ce livre est l'Ada d'aujourd'hui, Ada 95. Celui-ci étant relativement récent, nous avons pensé qu'il serait utile de fournir aux anciens utilisateurs des précisions sur les nouveautés apportées par la révision de la norme.
Aussi avons-nous divisé cette présentation en deux parties. La première explique simplement le «noyau de base», minimum nécessaire pour comprendre le reste de ce livre; presque tous ses éléments figuraient déjà dans Ada 83, et les utilisateurs actuels d'Ada pourront la survoler rapidement. La deuxième partie est plus technique et présente avec plus de détails les grandes lignes des nouveautés importantes. Sa lecture n'est pas nécessaire à la compréhension du reste de l'ouvrage, et ceux qui ne connaissent pas déjà le langage pourront la sauter.
Ce préambule ne cherche pas l'exhaustivité; pour une étude complète du langage, nous renvoyons le lecteur à la bibliographie en fin d'ouvrage.
=Origine d'Ada=
Historique.
En janvier 1975 le ministère américain de la Défense (DoD) a constitué un comité d'experts, le High Order Language Working Group (HOLWG), avec pour mission de trouver une approche systématique aux problèmes de qualité et de coûts des logiciels militaires.
La plus grosse part de ces logiciels, ou tout du moins là où résidaient les plus gros frais de maintenance, était dans le domaine des systèmes temps réel embarqués ("embedded"), c'est-à-dire des systèmes informatiques intégrés dans un ensemble électromécanique plus vaste : systèmes d'armes, de radar, de commutation...
Développer un langage de programmation universel apparut alors comme une solution à beaucoup de ces problèmes, et le HOLWG produisit une succession de cahiers des charges spécifiant les caractéristiques souhaitables d'un tel langage.
Au printemps de 1977 dix-sept organismes répondirent à l'appel d'offres, parmi lesquels quatre furent retenus pour une pré-étude : Softech, Intermetrics, SRI et Cii-Honeywell-Bull.
Les propositions furent évaluées de façon anonyme, et en mars 1978, il ne restait plus en lice qu'Intermetrics et Honeywell-Bull, l'équipe française dirigée par Jean Ichbiah remportant l'appel d'offre un an plus tard.
Le langage fut baptisé Ada, du nom d'Ada Augusta Byron.
Le document proposé en 1979 était en fait beaucoup trop vague pour permettre l'établissement d'un standard rigoureux.
Une première version révisée fut produite en juillet 1980, et l'on pensait à l'époque que le langage pourrait être normalisé avant la fin de cette même année. Il faut comprendre que la qualité de ce document était au moins aussi bonne que celle de la plupart des normes des autres langages de programmation. Mais pour Ada, il fallait faire beaucoup mieux ! En effet, le document comportait encore nombre de petites imprécisions, de possibilités d'interprétations divergentes ou de dépendances excessives à l'implémentation.
L'exigence de portabilité nécessitait une définition beaucoup plus précise, et il fallut attendre 1983 pour obtenir la standardisation par l'ANSI. La standardisation internationale exigeait que la norme fût déposée simultanément en deux des trois langues officielles de l'ISO qui sont l'anglais, le français et le russe.
Pour des raisons qui leur appartiennent, les américains préférèrent financer la traduction française plutôt que russe, et la normalisation internationale fut suspendue à la parution de la norme française. La traduction fut effectuée avec un soin extrême : il fallut attendre 1987 pour obtenir une norme satisfaisante [Afn87] et la standardisation ISO [Iso87].
Ada est également une norme européenne (C.E.N. 28652), allemande (DIN 66268), suédoise (SS 63-6115), tchèque, japonaise...
Il était important de définir rigoureusement le langage ; encore fallait-il que les compilateurs respectent la norme ! Pour cela, le DoD a déposé le nom «Ada», et l'autorisation d'utiliser ce nom pour un compilateur fut subordonnée à la confrontation avec succès du compilateur à une suite de validations.
Le premier compilateur Ada ainsi validé fut Ada/ED, réalisé par l'équipe de New York University.
De nombreux compilateurs ont été validés depuis.
Quelques années plus tard, le DoD a abandonné ses droits sur la marque, considérant que cette contrainte n'était plus nécessaire. Il a en revanche déposé une marque de certification, utilisable uniquement par les compilateurs validés. La notion de validation est maintenant tellement liée au langage Ada qu'il n'existe pas de compilateur non validé.
Il est de règle, cinq ans après la parution d'une norme, soit de confirmer le standard tel quel, soit de décider de mettre en route une révision. On savait dès le début que celle-ci serait nécessaire : certains pays n'avaient voté la norme d'origine que pour ne pas ralentir le processus de standardisation et à la condition qu'à la première occasion, on réglerait certains problèmes restés en suspens, principalement celui du jeu de caractères (Ada 83 utilisait l'ASCII 7 bits, qui est notoirement insuffisant pour les langues européennes).
Plusieurs autres facteurs concouraient à la nécessité d'une révision. D'abord, comme toute œuvre humaine, le standard comportait des imprécisions, des omissions et des ambiguïtés.
À l'ISO, un comité de maintenance, l'ARG (Ada Rapporteur Group),est chargé de régler ces problèmes ; une révision de la norme se devait d'incorporer ses décisions. Ensuite, la mise en œuvre pratique du langage a montré certaines petites faiblesses, ou la nécessité de certains mécanismes dus à l'évolution des modes de programmation (programmation orientée objet notamment).
Enfin, il y avait un désir de reformuler certaines règles afin de les rendre plus faciles à interpréter.
La décision fut donc prise en 1988 de démarrer le processus de révision. Le DoD fournit encore une fois le support financier nécessaire, et la révision fut conduite par l'Ada 9X Project Office, dirigé par Chris Anderson, qui confia la réalisation technique à une équipe d'Intermetrics conduite par Tucker Taft.
Dans la grande tradition d'ouverture d'Ada, un appel fut lancé aux utilisateurs pour connaître leurs desiderata. La réponse fut très importante, et une synthèse en fut tirée, regroupant par thèmes les principales tendances des demandes, et leur attribuant un degré de priorité. De cette synthèse on tira un document, le Mapping Document, destiné à décrire les transformations nécessaires pour satisfaire les points identifiés à l'étape précédente. Ce document, encore très touffu,comportait quasiment tout ce qu'il était envisageable de modifier, c'est-à-dire nettement plus qu'il n'était souhaitable.
Sur la base de ce document, une première réunion de l'ISO se tint au printemps 1992 dans la région de Francfort. Cette réunion marathon (50 participants de 12 pays travaillèrent de façon quasi ininterrompue, pendant une semaine, de 9h du matin à 11h du soir) permit d'aboutir à un accord unanime sur les éléments qu'il convenait de changer dans le langage. D'autres réunions internationales, à Salem puis à Boston (USA), permirent de préciser les détails de la révision. Une dernière réunion au mois de mars 1994 à Villars (Suisse) figea définitivement le langage. Les documents ne subirent alors plus que des changements éditoriaux pendant que le processus bureaucratique suivait son chemin, pour aboutir à l'enregistrement officiel par l'ISO le 15 février 1995.
Mais le temps continua à passer... 1995 plus cinq ans, vint le temps de décider de l'opportunité d'une nouvelle révision. En fait, dès novembre 1999 l'ISO prit la décision de ne pas commencer d'effort de révision. Bien entendu, la norme 1995 comportait des imprécisions et des erreurs qu'il fallait tout de même corriger. Il fut donc décidé de simplement faire paraître des corrigendums techniques pour tenir la définition du langage à jour. Un tel corrigendum technique a été officiellement approuvé le 1er juin 2001.
Un corrigendum technique ne peut que corriger des erreurs de définition du langage, il ne peut rien modifier fondamentalement, ni apporter d'améliorations. L'apparition de Java (avec la notion d'interfaces), certains problèmes pratiques apparus à l'usage, le besoin de nouvelles bibliothèques (conteneurs) demandaient des ajouts plus conséquents que ceux autorisés par le corrigendum. Il fut donc décidé début 2001 de préparer un amendement à la norme. Un amendement permet de rajouter de nouvelles fonctionnalités au langage, mais reste d'ampleur très inférieure à une révision. Le texte de l'amendement a été figé à la fin de 2005, ce qui fait que le langage est appelé Ada 2005, même si la parution officielle par l'ISO n'a été proclamée que le 9 mars 2007.
Objectifs du langage.
Contrairement à beaucoup de langages de programmation, Ada n'est pas le fruit des idées personnelles de quelque grand nom de l'informatique, mais a été conçu pour répondre à un cahier des charges précis, dont l'idée directrice était de diminuer le coût des logiciels, en tenant compte de tous les aspects du cycle de vie. Le langage est donc bâti autour de quelques idées-forces :
Au-delà du langage.
La définition d'un nouveau langage est une condition nécessaire, mais non suffisante, pour entrer dans une ère de production industrielle de logiciel. Aussi ne peut-il exister de compilateur Ada sans un environnement de programmation associé ; en particulier, le langage définit des règles très strictes concernant les dépendances entre unités de compilation, pour garantir la cohérence globale des différentes unités constituant un programme Ada. Ceci nécessite au moins un outil de gestion de projet associé. En fait, parallèlement à la définition du langage, se poursuivait un effort de définition de l'APSE (Ada Programming Support Environment) qui a abouti au rapport STONEMAN. Celui-ci définit les outils logiciels qui doivent faire partie d'un environnement de programmation Ada.
Aujourd'hui, il existe non seulement des compilateurs de qualité industrielle, mais aussi des outils d'environnement de haut niveau : metteurs au point symboliques, outils de gestion de projet, de documentation et de support méthodologique se sont multipliés. Les objectifs d'Ada sont ceux de tout le mouvement du génie logiciel, et le langage n'est qu'un élément qui s'intègre dans un ensemble, notamment méthodologique, plus vaste.
Exercices.
=Présentation du langage=
Ada est un langage algorithmique d'une puissance d'expression considérable, dérivé de Pascal dont il a retenu les structures de contrôle et certains types de données, mais avec en plus des possibilités d'encapsulation de données, de modularité, de modélisation de tâches parallèles, et de traitement des situations exceptionnelles. Ada reste un langage procédural « classique » (contrairement à LISP, SNOBOL, SETL ou Prolog par exemple), mais c'est un langage qui a un spectre sémantique assez vaste, et dont les apports originaux sont surtout du domaine de l'ingénierie du logiciel : fiabilité, maintenabilité, modularité, portabilité, réutilisabilité de composants logiciels.
Ada est-il un langage orienté objet ? Cette question a fait couler beaucoup d'encre. Ada 83 offrait un excellent support aux méthodes objet par composition mais n'avait pas de structure réalisant directement l'héritage ; il s'est ensuivi une querelle de mots pour savoir si Ada était « orienté objet » ou non, et l'utilisation parfois du terme « basé objet » (?) pour décrire les langages tels qu'Ada qui fournissaient indiscutablement la notion d'objet, tout en se passant fort bien de l'héritage... Ce débat n'a plus lieu d'être : la version 95 a apporté le support de l'héritage et des méthodes par classification. Nous discuterons complètement de ces questions dans la deuxième partie du livre, mais retenons que, maintenant, Ada est indiscutablement un langage orienté objet.
Un cadre général proche de Pascal.
Lors de l'appel d'offres qui conduisit à la définition d'Ada, il était spécifié que la proposition de langage devait être fondée sur la base d'un « grand » langage classique (Pascal, PL/1, Algol...).
Il est significatif que les quatre langages finalistes avaient tous choisi Pascal comme base de départ.
Le programme ci-dessous est un premier exemple qui imprime « Bonjour », « Bon après-midi » ou « Bonsoir » en fonction de l'heure de la journée.
with Text_IO, Calendar;
use Text_IO, Calendar;
procedure Bonjour is
 Heure : Day_Duration;
begin
 Heure := Seconds(Clock)/3600;
 if Heure < 12.00 then
 Put_Line ("Bonjour");
 elsif Heure < 19.00 then
 Put_Line ("Bon après-midi");
 else
 Put_Line ("Bonsoir");
 end if;
end Bonjour;
Il n'y a pas de construction spéciale pour désigner le programme principal : c'est une procédure comme les autres.
La clause codice_1 qui est en tête permet d'utiliser deux paquetages (packages) qui fournissent respectivement l'accès aux fonctionnalités d'entrées-sorties (codice_2) et à l'utilisation du temps (codice_3).
De façon générale, toute unité de compilation (structure pouvant être compilée séparément, comme les sous-programmes et paquetages) doit citer au début les autres unités qu'elle utilise au moyen d'une clause codice_1. La clause use est une simplification d'écriture dont nous reparlerons plus tard.
Les instructions de base sont inspirées de celles de Pascal (Figure 0), tout en tenant compte de ses imperfections reconnues : toutes les instructions se terminent par un point-virgule et les instructions structurées se terminent par un mot clé, éliminant ainsi le besoin de blocs begin..end (ou des accolades {..} de C).
<syntaxhighlight lang="ada">
if condition then
 instructions
elsif condition then
 instructions
else
 instructions
end if;
case expression is
 when choix 
Classification des paquetages.
L'écriture d'un système distribué nécessite certaines précautions.
Par exemple, si plusieurs partitions utilisent un paquetage « normal », celui-ci sera dupliqué dans chacune d'elles : s'il possède des états cachés, ils évolueront indépendamment dans chaque partition.
Si l'on souhaite un autre comportement, on peut fournir des pragmas de catégorisation pour définir des sémantiques différentes qui apportent les restrictions (vérifiées par le compilateur) nécessaires au bon fonctionnement du système.
On trouve ainsi :
Appels à distance.
Lorsqu'un sous-programme est défini dans un paquetage « interface d'appel distant », tous les appels sont routés vers la partition sur laquelle il se trouve physiquement.
De même, un pointeur sur un sous-programme défini dans un paquetage « interface d'appel distant » ou « types distants » est un type accès à distance (remote access type).
Ceci signifie que le pointeur contient l'information nécessaire pour localiser la partition où se trouve physiquement le sous-programme.
Tout appel à travers un tel pointeur sera également un appel distant. Les restrictions sur ces paquetages garantissent que les paramètres de tels sous-programmes sont toujours transmissibles sur le réseau.
De plus, lorsqu'un appel est transmis à travers le réseau, le compilateur doit utiliser pour le routage les services d'un paquetage prédéfini (System.RPC), dont le corps peut être fourni par l'utilisateur, le fournisseur du réseau, etc.
Le compilateur est ainsi indépendant de la couche « transport », et il est possible d'implémenter la distribution par-dessus n'importe quelle couche réseau sans avoir à toucher au compilateur.
Cohérence d'un système réparti.
Le problème de la cohérence d'un système réparti est délicat, car il doit répondre à deux exigences contradictoires :
Un programme Ada est dit « cohérent » si toutes les partitions qui le constituent utilisent la même version de toutes les unités de compilation.
On autorise un programme Ada à être incohérent, c'est-à-dire qu'il est possible de corriger une erreur qui n'affecte qu'une seule partition, d'arrêter la partition et de la relancer avec la nouvelle version.
Toutefois, si la correction implique un paquetage « partagé passif » ou « interface d'appel distant » (les seuls qui ne soient pas dupliqués), alors toute communication est coupée entre la nouvelle partition et le reste du système.
On autorise donc un système localement incohérent, tant que cela ne sort pas de la partition en cause ; la cohérence est exigée pour les seuls éléments qui sont physiquement répartis sur le réseau.
Enfin, chaque unité de compilation possède un attribut 'Version (pour la spécification) et 'Body_Version (pour le corps), dont la valeur change à chaque modification.
Il est donc possible de programmer des contrôles de cohérence plus fins si cela est nécessaire.
Le compilateur GNAT.
Un des obstacles importants à la diffusion d'Ada a longtemps été le prix des compilateurs, notamment pour les institutions universitaires.
Il est vrai que les fournisseurs ont consenti un important effort financier pour les organismes d'enseignement, mais le meilleur moyen de convaincre les gens d'utiliser Ada est de leur faire essayer le langage.
Or peu d'enseignants (aux crédits limités !) sont prêts à acheter un compilateur, même à prix réduit, juste pour voir...
Conscient de cet état de fait, le DoD a financé le développement d'un compilateur Ada 95 dont la diffusion est entièrement libre et gratuite.
Il s'agit en fait d'un frontal du célèbre compilateur multi-langages GCC, faisant partie de l'environnement GNU de la Free Software Foundation, connu sous le nom de GNAT (GNU Ada Translator).
La réalisation en a été confiée à la fameuse équipe de New York University, qui s'était déjà illustrée en réalisant le premier compilateur Ada (83) validé.
Comme tous les logiciels diffusés par la Free Software Foundation, GNAT est un logiciel libre, disponible non seulement sous forme exécutable, mais aussi sous forme de sources.
Tous les enseignants des cours de compilation peuvent ainsi offrir à leurs élèves d'intervenir dans un compilateur Ada, c'est-à-dire dans ce qui se fait de mieux en matière de compilation.
GNAT est disponible par les canaux de diffusion habituels du GNU, en particulier on peut le charger par FTP anonyme depuis tous les bons serveurs de logiciels libres.
Exercices.
Ces exercices s'adressent plus particulièrement aux anciens utilisateurs d'Ada 83.