Après plusieurs années passées à parlementer, la nouvelle norme Ada 2012 vient enfin d'être publiée par l'ISO sous le numéro ISO/IEC 8652:2012. Il s'agit donc de la quatrième révision du langage ajoutant ainsi différentes fonctionnalités par rapport à la version 2005.

NdM : GNAT est le compilateur Ada du projet GNU, faisant partie de GNU Compiler Collection (GCC). Toujours en logiciel libre, on peut citer MaRTE OS un système d'exploitation libre temps-réel en Ada.

Sommaire

Syntaxe

Les points suivants ont été modifiés ou ajoutés.

Le if en tant qu'expression

Les expressions contenant des if sont maintenant permises. On peut donc écrire :

Febdays : constant := ( if Leap then 29 else 28 );

Cela peut sembler idiot mais cela n'existait pas.

Le case en tant qu'expression

Les expressions contenant des case sont aussi autorisées.

Hours := ( case D is when Mon .. Thurs => 8 , when Fri => 6 , when Sat | Sun => 0 );

Les expressions quantifiées

Derrière ce nom barbare se cachent en fait deux nouveaux mot-clés all et some. L'exemple fourni dans le Rationale est le suivant :

B := ( for all K in A ' Range => A ( K ) = 0 );

qui mettra true dans la variable B si tous les éléments du tableau A sont à zéro. En substituant some à all, B vaudra true si seuls quelques éléments valent zéro.

Les fonctions unilignes

Une sorte de inlining a été ajouté au travers des fonctions expressions qui permet d'écrire le code sans passer par le classique duo begin…end si le code ne fait qu'une seule ligne.

Tests d'appartenance

Les tests d'appartenance ont été étendus pour ajouter le | dans le test. Il est donc possible d'écrire :

if M in Spring | June | October .. December then

Enfin, mais cela ne fait pas l'objet d'un paragraphe car très spécifiques, les règles de conversion dans certains cas d’ambiguïtés ont été assouplies.

Ajouts liés à la lisibilité

Un ensemble de changements a été fait pour améliorer le comportement du compilateur et les règles de vérification.

Sur les paramètres de fonctions et procédures

Un premier changement est l'ajout du mode in out pour les paramètres des fonctions. Cela introduit du coup une restriction qui est somme toute assez logique. Une fonction définissant un tel paramètre ne peut plus être incluse dans un autre appel directement si l'un de paramètres est aussi paramètre de l'appel du niveau supérieur.

Le second changement est la possibilité d'utiliser le mot clé aliased explicitement pour forcer un passage des paramètres par référence quelque soit leur type, cela n'était pas le cas pour les types simples. De plus, la possibilité pour une fonction de retourner des objets sous la forme aliased a été retirée pour éviter de potentiels problèmes de pointeurs pendants.

En vrac

Les autres changements sont donnés en vrac car requièrent réellement une bonne connaissance du langage :

Possibilité d'initialiser un discriminant y compris sur les types taggés limités ;

Ajout d'un use all type permettant d'ajouter l'intégralité des opérations liées à un type importé au lieu du cas par cas utilisé auparavant ;

Extension des possibilités du return.

Vérification statique

Pré-conditions et post-conditions

La gestion des pré-conditions et post-conditions dans la définition des fonctions a été ajoutée au langage. On peut maintenant préciser :

procedure Push ( S : in out Stack ; X : in Item ) with Pre => not Is_Full ( S ), Post => not is Empty ( S );

Les invariants

La prise en charge des définitions d'invariants a été ajoutée pour permettre l'écriture suivante :

type Disc_Pt is private with Type_Invariant => Check_In ( Disc_Pt );

Les paramètres passés lors de la création d'un objet du type seront vérifiés.

Multitâche

Le principal ajout dans ce domaine est lié aux capacités multi-processeurs et à leur contrôle. Grâce à l'ajout d'un sous-paquetage spécifique, il est maintenant possible d'avoir accès aux informations relatives aux processeurs présents sur la machine. Cela permet au travers d'une spécification d'aspect (comme pour les pré et post-conditions) de préciser sur quel CPU une tâche doit tourner.

task My_Task with CPU => 10 ;

En plus de cet ajout, on trouve maintenant la possibilité d'avoir un compte-rendu du temps passé dans les interruptions, le pragma Volatile devient un aspect et enfin une correction sur le mécanisme requeue pour les objets impémentant une interface synchronisée.

Associé au multitâche, un dernier ajout a été fait. Il s'agit du passage du profil de programmation Profil_Ravenscar au architecture multi-processeurs.

Bibliothèque standard

Si tout ce qui précède touchait majoritairement le langage en lui-même, certains ajouts ont été faits sur la bibliothèque standard.

Codage de chaînes

Une nouvelle partie vient compléter la gestion des chaînes de caractères en fournissant les mécanismes de codage vers UTF8, UTF16 Big Endian et UTF16 Little Endian avec prise en charge du Byte_Order_Mark alias BOM. Elle fournit donc les transcodages entre types UTF et les conversions de String, Wide_String et Wide_Wide_String vers UTF.

Les conteneurs

Différents types de conteneur ont été ajoutés pour fournir de nouvelles fonctionnalités. On trouve donc les arbres multiples ainsi que des versions à stockage limité des tables de hachage, listes chaînées et doublement chaînées et des maps. A aussi été ajoutée une série de conteneurs utilisables en programmes multitâches. Bref, de quoi coller à quasiment toutes les utilisations.

Internationalisation

Pour finir, on trouve un petit paquetage pour un embryon de gestion de l'internationalisation. Son but est juste de fournir la langue et le pays définis au sein du système d'exploitation.

Conclusion

À quelques jours près, la sortie de la dernière mouture a bien failli coïncider avec l'anniversaire d'Ada Lovelace ce qui aurait été un symbole fort, mais bon, l'ISO ne prenant pas de soumission pour ce jour-là, cela n'a pas été possible. Finalement, Ada se modernise encore un peu plus, tout en conservant ses aspects liés à la programmation sécurisée ce qui, pour un langage déclaré mort maintes fois, n'est quand même pas si mal.

Aller plus loin