IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Ada Discussion :

Type, Subtype, Convertible


Sujet :

Ada

  1. #1
    Inactif Avatar de Hibou57
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    852
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 852
    Points : 493
    Points
    493
    Par défaut Type, Subtype, Convertible
    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...

    type Montant is digit 2; -- Les valeurs ont deux décimales
    Ce type Montant est abstrait, car il existe plusieurs monnaies dans le monde.

    type Montant_Yen is new Montant; -- Japon
    type Montant_Dirham is new Montant; -- Maroc
    type Montant_Euro is new Montant; -- Europe
    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é.

    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.

    E : 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
    C'est bien ce que nous voulons... Ada est trés bien

    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.

    subtype Petite_Depense is Montant_Euro range 0..20;
    subtype Grosse_Depense is Montant_Euro range 21..300;
    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.

    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).
    Avec subtype, nous introduisons donc une nuance de type, tout en se réservant la possibilité de mélanger ces types.

    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 ...

    type Clee is ....; -- Ce que vous voulez
    type Clee_Porte_Entree is new Clee;
    type Clee_Porte_Garage is new Clee;
    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...

    procedure Rendre_Clee (Une_Clee : 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).

    fonction Clee_Simple (C : Clee_Porte_Entree) return Clee;
    fonction Clee_Simple (C : Clee_Porte_Garage) return 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.

    Et nous pourront avoir ...

    CE : Clee_Porte_Entree;

    Rendre_Clee (Clee_Simple (CE));
    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.

    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
    ------------------------------------------------------------
    Sur le web, c'est la liberté qui est gratuite, mais bien évidement pas la consomation ... et encore moins la consomation à outrance
    ------------------------------------------------------------
    Language shapes the way we think, and determines what we can think about [ B. Lee Whorf ] ... mais ce n'est pas tout à fait vrai à 100%...
    ------------------------------------------------------------
    Pascal (FreePascal?) - Ada (Gnat-3.15p)
    XSLT (XSLTProc) - CGI binaires (Ada/C) [ Clavier Arabe ]
    ------------------------------------------------------------

  2. #2
    HRS
    HRS est déconnecté
    Membre confirmé
    Avatar de HRS
    Inscrit en
    Mars 2002
    Messages
    677
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 677
    Points : 638
    Points
    638
    Par défaut
    pas besoin de créer des fonctions de conversion.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    procedure Conver is
       type Newint is new Integer;
       Int1    : Integer := 3;
       Newint1 : Newint  := 2;
    begin
       Int1 := Integer (Newint1);
       Newint1 := Newint (Int1);
    end Conver;

  3. #3
    Inactif Avatar de Hibou57
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    852
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 852
    Points : 493
    Points
    493
    Par défaut
    Alut ...

    Beh, l'idée que j'avais, c'est que je trouve plus claire de déclarer des fonctions de convertions avec les déclaration des types, comme ça on voit immédiatement les relations apparaîtrent dans la spécification du package... La démarche est plus rigoureuse, plus propre, et ne cache rien.

    Disont que la solution que tu donne permet justement d'implémenter de telle fonctions de convertion, mais je ne pense pas qu'il faille trop l'utiliser sous cette forme...

    D'ailleurs ce n'est pas toujours exact. Imagine que tu as un type Lettre_Alphabet... tu en dérive les types Lettre_Arabe, Lettre_Latine... tu veux convertire Lettre_Arabe vers Lettre_Latine ou vice-versa... la solution que tu donne ne convient pas, car il faut établire des correspondances particulières.

    Autre exemple, pour reprendre le cas des clées justement... Même s'il est implanté avec un type Integer, par exemple, le type Clee serait probablement private, car l'application utilisatrice du package ne devrait surement pas avoir le droit de créer des clées comme bon lui semble, au gré de ses fantaisies... Elle ne va surement pas créer une variable Clee, et lui affecter n'importe quelle entier comme elle l'entend... ce serait un mauvais design.

    Quand tu déclare Newint, Ada considère ce type comme incompatible avec Integer... c'est bien parce que formellement il n'y a pas de convertions directes sans preuve qu'elle doivent êtres faites de la sorte.

    Cette convertion de la forme Type_Truc (xxxx), ne devrait être utiliser que dans l'implémentation du package qui définie Type_Truc (d'ailleurs je pense que les spécifications de Ada auraient dut imposer cette restriction... sur ce point, Ada n'est pas assez stricte à mon gout )

    C'est mon sentiment question Design ...

    Tu en penses quoi ?
    ------------------------------------------------------------
    Sur le web, c'est la liberté qui est gratuite, mais bien évidement pas la consomation ... et encore moins la consomation à outrance
    ------------------------------------------------------------
    Language shapes the way we think, and determines what we can think about [ B. Lee Whorf ] ... mais ce n'est pas tout à fait vrai à 100%...
    ------------------------------------------------------------
    Pascal (FreePascal?) - Ada (Gnat-3.15p)
    XSLT (XSLTProc) - CGI binaires (Ada/C) [ Clavier Arabe ]
    ------------------------------------------------------------

  4. #4
    Futur Membre du Club
    Inscrit en
    Juin 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 7
    Points : 8
    Points
    8
    Par défaut
    Si tu veux limiter les opérations, alors passe par un type limité privé.
    Là, aucune opération ne sera accessible aux utilisateurs hormis celles que tu définis.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    package Dummy_P is
     
      type Cle_maison is limited private;
      type Cle_garage is limited private;
     
      procedure Rendre_Cle(Cle : in Cle_Maison);
      procedure Rendre_Cle(Cle : in Cle_Garage);
     
    private 
     
      type Cle is new ....; 
      type Cle_maison is new Cle;
      type Cle_garage is new Cle;
     
    end Dummy_P;
    Ca évite que l'utilisateur additionne des clés, essayent de transformer une clé de garage en clé de maison et autres joyeusetés.
    Et comme il n'y a pas de Cle_Simple utlisable, aucune raison de donner accès à ce type à l'utilisateur. Moins il a accès aux bidouilles internes, moins il fait de bugs.

    Maintenant, pour l'affaire des clés, j'aurais utilisé des types taggés plutôt, mais vu ce que tu veux illustrer, c'est HS. ^^

  5. #5
    Inactif Avatar de Hibou57
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    852
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 852
    Points : 493
    Points
    493
    Par défaut
    C'est vrai, j'ai oublié de parler de private et limited private... Merci BoubaStyle

    Bon, je reconnais bien l'intérêt de ta version du package pour les clées... en fait, je cherchais un exemple ou on peut avoir des relations de conversion typique, comme parent vers enfant, ou enfants vers parents, vu que Ada, soit autorise tout les mélange (subtype), soit les interdit tous (type-new).

    Je ne sais pas si je m'exprime bien ....

    Peut-être que quelqu'un(e) a un autre exemple tiré de son expérience ?

    P.S. c'est comme ça que j'opère personellement : en déclarant des fonctions de convertions, pour que les relations entre types apparaissent clairement... mais je suis prenneur d'autres idées s'il y en a
    ------------------------------------------------------------
    Sur le web, c'est la liberté qui est gratuite, mais bien évidement pas la consomation ... et encore moins la consomation à outrance
    ------------------------------------------------------------
    Language shapes the way we think, and determines what we can think about [ B. Lee Whorf ] ... mais ce n'est pas tout à fait vrai à 100%...
    ------------------------------------------------------------
    Pascal (FreePascal?) - Ada (Gnat-3.15p)
    XSLT (XSLTProc) - CGI binaires (Ada/C) [ Clavier Arabe ]
    ------------------------------------------------------------

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [C#] Convertion de type (string/int)
    Par M1000 dans le forum Windows Forms
    Réponses: 4
    Dernier message: 22/05/2006, 16h03
  2. Convertion d'un type Nombre en type Date
    Par jam92400 dans le forum Access
    Réponses: 3
    Dernier message: 22/05/2006, 15h29
  3. convert type long en type money
    Par fix105 dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 07/02/2006, 16h42
  4. [SQL Server] Error converting data type varchar...
    Par Sir Tengu dans le forum MS SQL Server
    Réponses: 9
    Dernier message: 13/06/2003, 10h46
  5. Convertion de type VARIANT à type CString
    Par j_grue dans le forum MFC
    Réponses: 2
    Dernier message: 07/11/2002, 14h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo