Des petits exemples, pour bien comprendre une partie de la phylosophie du typage en Ada (vous êtes bienvenue pour signaler les erreurs, s'il y en a).
En Ada, le type peut être abordé de trois manières différentes
- Déclaration dérivée
ex. type Abc is new Def; -- avec/sans contraintes- Déclaration de subtype
ex. subtype Abc is Def; -- avec/sans contraintes- Définition de fonction de convertion
ex. function To_Def (x : Abc) return Def;
Voyons la sémantique est l'utilité de ces trois manières de traiter avec les types.
Començons par la première forme de déclaration...
Avec type-new, nous déclarons des types de choses qui ne se mélangent pas
Un exemple concret...
Ce type Montant est abstrait, car il existe plusieurs monnaies dans le monde.type Montant is digit 2; -- Les valeurs ont deux décimales
Nous avons maintenant déclaré trois types de montant, correspondant chacun à une monnaie. Ces trois montants auront tous deux décimales, ce qui caractérise un Montant, car c'est ainsi que nous l'avons déclaré.type Montant_Yen is new Montant; -- Japon
type Montant_Dirham is new Montant; -- Maroc
type Montant_Euro is new Montant; -- Europe
La déclaration type-new signifie que ces types ne pourront pas êtres mélangés. Ainsi, nous ne pourrons pas additionner des Yen et des Dirham, pas plus que nous ne pourrons affecter un Montant à un Montant_Euro.
C'est bien ce que nous voulons... Ada est trés bienE : Montant_Euro;
E2 : Montant_Euro;
Dh : Montant_Dirham;
Y : Montant_Yen;
E := Dh + Y; -- Interdit : pas Yen et Dirham !!!
E2 := E + E2; -- Ok, c'est normal
Ensuite, voyons l'utilité du subtype...
Avec subtype, nous déclarons des types différents, mais compatibles entre eux
Imaginons que nous voulions gérer notre petit budget familial, en Euro... Imaginons encore que nous voulions distinguer les petites dépenses et les grosses dépenses.
Ici, contrairement à la déclaration type-new, nous pourrons mélanger les petites dépenses et les grosses dépenses dans une même expression.subtype Petite_Depense is Montant_Euro range 0..20;
subtype Grosse_Depense is Montant_Euro range 21..300;
Avec subtype, nous introduisons donc une nuance de type, tout en se réservant la possibilité de mélanger ces types.T : Montant_Euro;
P : Petite_Depense;
P2 : Petite_Depense;
G : Grosse_Depense;
T := P + G; -- Autorisé
G := P + P2; -- Autorisé (si le total est assez grand).
Notez que dans G := P + P2; ... là, c'est le programme qui doit s'assurer que effectivement le résultat correspondra à une petite dépense, ... Ada levera une exception à l'execution, s'il s'avère que P + P2 est trop petit pour être une grosse dépense (l'environnement detectera que le résultat ne tient pas dans l'interval de Grosse_Depense).
On peut aussi bien sure écrire n'importe quoi, des erreurs comme par exemple une expression telle que P := T + G, qui produira logiquement toujours une erreur et donc une exeption à l'execution. Mais cela, le compilateur ne peut pas le savoir, car c'est le/la programmeur(se) qui est responsable du bon usage de ces types. Malgré tout, l'erreur sera detecté à l'execution.
Nous arrivons au troisième cas...
Avec les fonctions de convertions, nous mélangeons les choses selectivement
Imaginons que nous ayons ...
On ne melange pas les clées de porte d'entrée et les clées de garage... soit. Mais pourtant, on pourrait considérer qu'une clée de porte d'entrée est une clée tout-court. Ors, pour le moment, il nous est impossible par exemple, d'affecter une Clee_Porte_Entree à une Clee. C'est prévisible, car nous avons employé type-new, parce qu'on ne doit pas mélanger les clées de n'importe qu'elle manière, même si on veut que ce soit possible dans certains cas, comme quand il s'agit de rendre une clée par exemple...type Clee is ....; -- Ce que vous voulez
type Clee_Porte_Entree is new Clee;
type Clee_Porte_Garage is new Clee;
On aura alors besoin d'une fonction de convertion, que l'on devra obligatoirement créé nous-mêmes, car Ada, dans sa grande sagesse, considère qu'il ne peut pas correctement deviner à quoi nous pensons, et comment la conversion s'opère, ni quels controls doivent êtres effectués, pour s'assurer que la convertion est légale (vous-vous doutez bien que Ada ne sait pas ce que sont des clées, et qu'il ne connait pas non-plus tout ce que vous pourrez encore imaginer).procedure Rendre_Clee (Une_Clee : Clee);
Maintenant, une clée de porte d'entrée, peut être reconnue comme une clée tout court, mais ne pourra pas être assimilée à une clée de garage.fonction Clee_Simple (C : Clee_Porte_Entree) return Clee;
fonction Clee_Simple (C : Clee_Porte_Garage) return Clee;
Et nous pourront avoir ...
Note : certain(e)s auraient peut-être créé une fonction générique, mais dans les cas restreints, comme celui-ci, il n'est pas nécéssaire de sortire le pilon pour planter un punaise.CE : Clee_Porte_Entree;
Rendre_Clee (Clee_Simple (CE));
En résumé
Nous utilisons ...
- Type-new pour les choses qui ne doivent pas êtres mélangées entre elles
- Subtype pour les choses qui peuvent être mélangées entre elles
- Une/des fonction(s) de convertion(s) avec type-new, quand les choses peuvent être mélanger entre elles, mais seulement dans certains sens.
:p
Amusez-vous bien ... bye-bye
Partager