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

Langages de programmation Discussion :

Les avantages du procédurals par rapport à l'orientée objet?


Sujet :

Langages de programmation

  1. #81
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par alex_pi Voir le message
    Un exemple qui parle peut être plus serait celui d'éléments graphique "affichable". Si j'ai des carrés et des ronds, en procédural, il va me falloir une fonction affiche_carre et une fonction affiche_rond et il faudra que je sache initialement laquelle appeler, alors qu'en objet, il suffit que mes carrés et mes ronds aient tous les deux une méthode afficher que je peux appeler "aveuglément".
    Citation Envoyé par alex_pi Voir le message
    Euh non. Même avec module, tu ne peux pas avoir une fonction qui attends un truc "imprimable" et qui l'imprime, sans se préoccuper de ce que c'est. En OCaml, tu as les objet (ou les types unions et une grosse fonction de dispatche dynamique) et en haskell les type class. Par contre les modules n'y changent rien.
    Je n'y comprend rien du tout...

    Cela fait plus de 25 ans que je fais du graphisme, et, à part au dernier niveau le plus bas, je n'ai jamais appelé une fonction affiche_carré ou affiche_rond, mais affiche_data.. qui appellera affiche_symbole

    Je crois que tu confonds beaucoup de choses...


    Moi aussi j'appelle "aveuglément"...

    (et si tes structures ou APIs sont bien définis, tu n'as même pas besoin de "méthodes" différentes, ou de "switch case" différents).

    Quand ton Ocaml ou Java ou n'importe quoi dispatche, c'est bien que cela appelle la méthode propre , non ? qu'est-ce qu'il y a de si différent ???

  2. #82
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    Jà part au dernier niveau le plus bas, je n'ai jamais appelé une fonction affiche_carré ou affiche_rond,
    Donc au dernier niveau le plus bas, il peut t'arriver de distinguer affiche_carre ou affiche_rond ?

  3. #83
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par millie Voir le message
    Donc au dernier niveau le plus bas, il peut t'arriver de distinguer affiche_carre ou affiche_rond ?
    eventuellement, mais même pas sûr... (on peut faire une seule routine Affiche_Symbole à laquelle on passe (ou elle se démerde) le type).

    MAIS par contre j'ai une seule routine de céation, un seul type d'objet..

    D'après ce que je comprend, dans le cas d'Alex, il y aurait 2 routines de création, avec 1 routine (en fait 2, mais cachées) d'affichage.

    Ce serait juste à l'écriture dans le code d'utilisation qu'on ferait Object.Draw au lieu de faire Draw_Object ( Object );


    Je ne vois pas vraiment la différence... En nombre de lignes de code il y en au moins autant sinon plus (2 méthodes à écrire).

    En nombre de fichiers kif kif, si c'est un gros projet, il y aura autant de fichiers que de classes..

    J'aimerais avoir un exemple de code comme l'entend Alex : création de 2 objets carre et rond, settings des valeurs, puis admettons le cas qu'on a une image sur laquelle on a tracé ces 2 objets. On a une boucle infinie (celle de l'outil) qui vérifie les évènements. On sélectionne un des objets. Alors je voudrais aussi la méthode de sélection.

    Et on comparera avec ce que j'aurais fait..


  4. #84
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Justement si.
    Pourquoi serait-ce de l'objet mal utilisé ?
    Vous vous attachez trop aux conventions d'écriture. C'est un détail d'implémentation propre à chaque langage, et sans la moindre importance.

    Que l'on écrive obj.operation(), (operation obj), ou operation(obj), il n'y a aucune différence.
    Je reprends mon explication qui n'a pas été claire.

    Dans une vision procédural du monde, les "trucs" qu'on manipule (appelons les des éléments) ne contiennent que des données. Si on veut pouvoir utiliser ces données, il faut impérativement que l'élément expose sa structure interne au reste du monde pour que les procédure puisse le manipuler. Et inversement, une procédure devient complètement dépendante de la structure interne de l'élément. Ainsi, on ne peux pas écrire une procédure qui sait trier à la fois les tableau et les listes. C'est pourquoi il faut écrire une procédure qui trie les tableaux, une autre qui trie les liste. Et sur les tableaux, il faut appeler celle qui trie les tableaux, et inversement. Si on se trompe, soit on est dans un bon langage, et on se fait jeter par le typeur à la compilation, soit on est dans un mauvais, et ça crash à l'exécution.

    Dans une vision objet du monde en revanche, les "trucs" qu'on manipule (appelons les des... objets :-D) contiennent à la fois des données et des méthodes qui savent manipuler ces données. L'objet n'est plus alors obligé de présenter au monde sa structure interne, mais juste ses méthodes et leur signature (ce que l'ont appelle plus communément leur type). On peu ainsi dire qu'un objet est "triable" si et seulement si il a une méthode "tri" qui n'attend pas d'argument et ne retourne rien.

    Et la notation a un sens. Quand on écrit monObjet.tri(), on appelle la méthode tri spécifique à l'objet. On n'a aucun besoin de savoir quel type d'objet c'est, juste qu'il dispose d'une méthode tri. Ca peut être une liste, un tableau, autre chose, peu importe. Le choix du code réellement exécuté se fait dynamiquement, mais de façon transparente au programmeur, et sûre.
    En revanche, quand on écrit tri42(monElement), il faut être sur que monElement est bien du type attendu par la procédure tri42, ce qui n'a rien à voir. Il n'y a qu'une seule procédure portant le nom tri42, et il ne faut pas se planter, sinon, boom.

    J'espère que c'est plus clair.

  5. #85
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    Je crois que tu confonds beaucoup de choses...
    Ne t'en déplaise, je pense avoir une connaissance raisonnable dans le domaine des langages de programmation, des types et de ce genre de choses.

    Citation Envoyé par souviron34 Voir le message
    Je n'y comprend rien du tout...

    Cela fait plus de 25 ans que je fais du graphisme, et, à part au dernier niveau le plus bas, je n'ai jamais appelé une fonction affiche_carré ou affiche_rond, mais affiche_data.. qui appellera affiche_symbole
    Citation Envoyé par souviron34 Voir le message
    Moi aussi j'appelle "aveuglément"...

    (et si tes structures ou APIs sont bien définis, tu n'as même pas besoin de "méthodes" différentes, ou de "switch case" différents).

    Quand ton Ocaml ou Java ou n'importe quoi dispatche, c'est bien que cela appelle la méthode propre , non ? qu'est-ce qu'il y a de si différent ???
    Dans le cas d'un langage "objet", le dispatch dynamique est un trait du langage. Quand j'envoie un message à mon objet, je sais que la bonne méthode sera exécuté, qu'elle sera bien typé, etc.

    Dans ton cas, c'est quelque chose de proposé par la librairie. En gros, GTK, il fait de l'objet en C (et si c'est pas GTK, c'est probablement la même chose). C'est la libraire qui se charge d'implémenter de façon ad-hoc le dispatch dynamique. Les deux options sont soit d'avoir un tableau de poiteur de fonction, soit que l'objet trimbale son type, qui en fait sera un simple entier, et la fonction fait un switch. Dans les deux cas, c'est non typé. Donc pour une librairie, bon, on va dire que c'est suffisamment testé pour espérer que ça va bien se passer. Dans le cas d'une utilisation ponctuelle, on va dire qu'il faut avoir confiance en soit.

  6. #86
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    @alex_pi : En fait, je pense qu'il y a 2 choses à expliquer séparément.

    Le coup des fonctionnalités attachées à un type abstrait de données (méthode) et le coup de procédure indépendante de l'objet manipulé qui dispose de fonctionnalités précises.

    Par exemple, on peut avoir une fonction max() qui retourne l'entier le plus élevé d'un machin qu'on peut appeler une collection (que ce soit un tableau, un ensemble, une liste) que l'on peut simplement écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int max(UneCollection c) {
      Si la taille de c est nulle => erreur
    
      entier max = choisir un élément de c
      Pour tout element e de c faire
         Si max< e 
            max = e;
      retourner max;  
    }
    Ici, l'interêt est juste que l'algorithme (et le code) est indépendant du genre de collection.

    En langage procédural avec pointeur de fonction, il faudrait quelque chose du genre :

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int max(void * macollection, fonction choisirElement(macollection) -> entier, 
      fonction elementSuivant(macollection) -> entier, fonction dernierElement(macollection) -> boolean, fonction vide(macollection) -> boolean {
       Si vide(macollection)  -> erreur
       entier max = choisirElement(macollection);
       ...
    }

    On pourrait imaginer que macollection contienne déjà ces fonctions (au lieu de les passer en paramètres). Mais c'est en fait de la POO écrit en langage procédural avec pointeur de fonction !

  7. #87
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 279
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 279
    Points : 11 015
    Points
    11 015
    Par défaut
    Ce n'est pas parce que les langages maintream n'appliquent pas de liaison tardive sur l'argument que l'on ne pourrait pas avoir un langage qui comprend que foo(o) doive aller chercher l'opération (au sens OO -- je n'aime pas "méthode") foo associée au type exact de l'objet o.
    Ce n'est qu'une question de syntaxe et de convention d'écriture.

  8. #88
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Ce n'est pas parce que les langages maintream n'appliquent pas de liaison tardive sur l'argument que l'on ne pourrait pas avoir un langage qui comprend que foo(o) doive aller chercher l'opération (au sens OO -- je n'aime pas "méthode") foo associée au type exact de l'objet o.
    Ce n'est qu'une question de syntaxe et de convention d'écriture.
    Mais ce n'est pas du procédural, c'est de l'objet avec une syntaxe différente... C'est toi qui te focalise de façon completement hors sujet sur la syntaxe...

  9. #89
    Membre chevronné

    Homme Profil pro
    Architecte logiciel
    Inscrit en
    Novembre 2006
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte logiciel
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 252
    Points : 1 954
    Points
    1 954
    Par défaut
    En langage objet tu peux écrire une fonction de tri (une méthode statique)unique qui s'applique sur n'importe quel type de collection, pour peu quelle obéisse à un comportement prédéfini.

    Ainsi, je peux écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      Tableau a;
      ListeChainee b;
    
      Util.tri(a)
      Util.tri(b)
    En procédural, tu ne peux pas, tu es obligé d'écrire plusieurs fonctions de tri, une adaptée à chaque type de collection.

  10. #90
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Ce n'est pas parce que les langages maintream n'appliquent pas de liaison tardive sur l'argument que l'on ne pourrait pas avoir un langage qui comprend que foo(o) doive aller chercher l'opération (au sens OO -- je n'aime pas "méthode") foo associée au type exact de l'objet o.
    Ce n'est qu'une question de syntaxe et de convention d'écriture.
    Pour moi, un langage avec cette propriété est quasiment un langage orienté objet (voir en est un).

  11. #91
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    J'aimerais avoir un exemple de code comme l'entend Alex : création de 2 objets carre et rond, settings des valeurs, puis admettons le cas qu'on a une image sur laquelle on a tracé ces 2 objets. On a une boucle infinie (celle de l'outil) qui vérifie les évènements. On sélectionne un des objets. Alors je voudrais aussi la méthode de sélection.

    Et on comparera avec ce que j'aurais fait..

    Allez, puisqu'on est sur le forum "Langages en Général", amusons nous, ne faisons pas le sempiternel Java/C++

    Soit un rectangle, défini par son coin supérieur droit, et dont on peut calculer l'aire. On peut aussi multiplier les coordonnées, juste pour dire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    let rect = 
    object 
      val mutable sdx = 1.
      val mutable sdy = 2.
      method shrinkx sx = 
        sdx <- sdx *. sx
      method shrinky sy = 
        sdy <- sdy *. sy
    
      method surface = 
        sdx *. sdy
    end;;
    OCaml a la gentillesse de nous en donner le type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    val rect :
      < shrinkx : float -> unit; shrinky : float -> unit; surface : float > =
      <obj>
    On constate seules les 3 méthodes sont présentées dans le type, pas les champs.

    On définis un cercle. Juste un rayon ce coup ci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    let cercle = 
    object 
      val mutable rayon = 1.
      method shrink s = 
        rayon <- rayon *. s
    
      method surface = 
        3.14159 *. rayon *. rayon
    end;;
    Ce coup ci, on obtient le type

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    val cercle : < shrink : float -> unit; surface : float > = <obj>
    Ah tiens, au passage, on peut constater qu'on n'a pas eu besoin de définir de classe. Le type d'un objet est en fait uniquement la liste de ses méthodes avec leur signature. Le fait que les langages "mainstream" se sentent obligée de passer par des classes n'a rien à voir avec le schimilibili.

    On peut manipuler nos deux objets

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    rect#shrinkx 3.;
    rect#shrinky 2.;
    rect#surface;;
        - : float = 12.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    cercle#shrink 2.;
    cercle#surface;;
      - : float = 12.56636
    Maintenant on veut les utiliser en même temps

    Pour ça on va créer une "image", qui est un ensemble d'objet avec une méthode "surface". Pour rire, on va faire une classe ce coup ci.

    Tout d'abord, définition d'une interface
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class type surf = 
    object
      method surface : float
    end;;
    Puis la classe image qui utilise cette interface (et l'implémente aussi, mais c'est accessoire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class image =
    object
      val mutable l : surf list  = []
      method add s  = l <- s :: l
      method surface = 
        List.fold_left (fun acc s -> acc +. s#surface) 0. l
    end;;
    Utilisons l'image
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    let im = new image;;
    
    im#add (rect :> surf) ;
    im#add (cercle :> surf);
    im#surface;;
    
    - : float = 24.56636
    On peut bien sûr rajouter de nouveaux objets
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    let patatoide = object method surface = 42. end;;
    
    im#add patatoide;
    im#surface;;
    
     - : float = 66.56636
    L'image n'a aucune raison de savoir quels objets elle contient, elles doit juste savoir qu'il y a une méthode surface. Ca, sans objet, c'est pas trivial...

  12. #92
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par alex_pi Voir le message
    L'image n'a aucune raison de savoir quels objets elle contient, elles doit juste savoir qu'il y a une méthode surface. Ca, sans objet, c'est pas trivial...
    Je ne connais rien à Ocaml, à la limite je peux lire du C++ ou du Pascal Object..

    Je peux cependant à peu près deviner ce que tu fais là-haut..

    Maintenant voici ce que je ferais :

    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    typedef struct pObjet {
        int Type ;
        int x  ;
        int y ;
        int width ;
        int height ;
    } Objet ;
    
    #define RECT 0
    #define ELLIP 1
    ....
    
    Objet MesObjs[2] ;
    Widget Image ; /* Par exemple, n'importe quel objet de style graphique */
    
    
    MesObjs[0].Type = RECT ;
    MesObjs[1].Type = ELLIP ;
    
    for ( i = 0 ; i < 2 ; i++ )
    {
       MesObjs[i].x = 100 + i*100 ;
       MesObjs[i].y = 100  ;
       MesObjs[i].width = 80 ;
       MesObjs[i].height = 50 ;   
    } 
    
    ...
    
    Get_Mouse ( Image, &posx, &posy ),
    Select_Objet (MesObjs, posx, posy );
    ..
    
    
    void Select_Objet ( Objets *LesObjets, int x, int y ) /* x, y position souris */
    {
       Objet CetObj ;
    
       Get_Select (LesObjets, x, y, &CetObjet);
    
       Draw_Enhanced ( &CetObjet );
    }
    
    
    void Draw_Enhanced ( Objet *ObjetATracer )
    {
        switch ( ObjetATracer->Type )
         {
            case ELLIP ;
                   XDrawArc () ... ; /* avec X11, ou GTKDraw.. si ça existe */
                   break ;
             case RECT :
                   XDrawRect ()... ; /* avec X11, ou GTKDraw.. si ça existe */
                   break ;
         } 
    }
    En gros, bien sûr...

    Je ne vois pas de gain particulier de code ou de connaissance plus élevée pour la création ou la manipulation...

    Tu remarqueras qu'avec la même méthode je trace des rectangles, des carrés, des cercles ou des ellipses..

    MAIS que toute autre utilisation à part l'initialisation est indépendante du type de l'objet...

    Maintenant, l'image n'a effectivement aucune raison de savoir ce qu'elle contient.. Juste une série d'Objets...


    Et encore, là, je passe directement.

    Mais dans la vraie vie, j'ai par exemple une grosse structure comprenant tous mes paramètres d'interfaces, mes data, etc etc.., et je ne passe comme paramètre que le pointeur sur cette structure, chaque routine ne prenant que ce qui la concerne.... Et le pointeur va jusqu'en bas...



    Note : Je ne pourrais pas lire les commentaires avant demain soir...



    PS 1: je ne dis pas que c'est forcément mieux, mais que (à part peut-être avec OCaml dont on a déjà discuté et dont la syntaxe m'apparaît plus qu'obscure), pour des langages objets "courants", je ne pense pas que coder l'équivalent soit plus léger...

    PS 2 : tu as à peu près le même nombre de lignes que moi, et pour tes additions de surface ou tes calculs, il te faut bien les coder... Car ton .add recouvre bien du code quelque part...

    PS 3 : je peux te sortir un exemple de la vie réelle où j'ai à peu près 10 à 15 couches entre le haut et le bas, et ce n'est que dans la dernière tout en bas que je me préoccupe du type de l'objet manipulé...

  13. #93
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Tommy31 Voir le message
    En langage objet tu peux écrire une fonction de tri (une méthode statique)unique qui s'applique sur n'importe quel type de collection, pour peu quelle obéisse à un comportement prédéfini.

    Ainsi, je peux écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      Tableau a;
      ListeChainee b;
    
      Util.tri(a)
      Util.tri(b)
    En procédural, tu ne peux pas, tu es obligé d'écrire plusieurs fonctions de tri, une adaptée à chaque type de collection.
    Encore une fois, c'est une facilité () d'écriture, ce qui ne t'empêche pas d'avoir à les coder séparément...

    Me trompe-je ? (à part OCaml)

    En C, l'algorithme de qsort est commun à tout (ton Util.tri) , c'est juste la fonction de comparaison qui est distincte..

    Mais tu peux écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    qsort ( a ...);
    qsort ( b ...);
    Et je ne vois pas comment un langage objet pourrait deviner sur quel élement il doit faire le tri ni comment... Un tri ascendant sur des flottants ou sur une chaîne de caractère c'est pas la même chose... de même que sur des entiers ou les jours des mois (qui se resettent à chaque fin de mois)

  14. #94
    Inactif  
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    1 958
    Détails du profil
    Informations personnelles :
    Âge : 59
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 1 958
    Points : 2 467
    Points
    2 467
    Par défaut
    Citation Envoyé par alex_pi Voir le message
    [...]
    Il faut se souvenir qu'en objet, un appel de méthode n'est pas un appel de fonction comme les autres. C'est un envoi de message[...]
    En procédural en revanche, il faut savoir quel objet on a sous la main[...]

    Un exemple plus que classique est celui d'un conteneur. [...]
    En procédural, quand je reçois un tel conteneur, il faut que je découvre de quel type il est pour pouvoir appeler la bonne fonction de tri dessus (tri_tableau, trie_liste, etc) alors qu'en objet, j'envoie juste un message disant "trie toi" à mon objet.[...]
    Citation Envoyé par alex_pi Voir le message
    Justement pas dutout !
    Quand j'écris l.tri(), je n'ai pas besoin de savoir si l est une liste ou un tableau, juste que c'est un objet avec une méthode tri. En revanche, si j'écris tri_liste(l), il faut que je sache que l est une liste pour savoir comment le trier.[...]
    Citation Envoyé par alex_pi Voir le message
    [...]
    Dans une vision procédural du monde, les "trucs" qu'on manipule (appelons les des éléments) ne contiennent que des données. Si on veut pouvoir utiliser ces données, il faut impérativement que l'élément expose sa structure interne au reste du monde pour que les procédure puisse le manipuler. Et inversement, une procédure devient complètement dépendante de la structure interne de l'élément. Ainsi, on ne peux pas écrire une procédure qui sait trier à la fois les tableau et les listes. C'est pourquoi il faut écrire une procédure qui trie les tableaux, une autre qui trie les liste. [...]
    Dans une vision objet du monde en revanche, les "trucs" qu'on manipule (appelons les des... objets :-D) contiennent à la fois des données et des méthodes qui savent manipuler ces données. L'objet n'est plus alors obligé de présenter au monde sa structure interne, mais juste ses méthodes et leur signature (ce que l'ont appelle plus communément leur type). On peu ainsi dire qu'un objet est "triable" si et seulement si il a une méthode "tri" qui n'attend pas d'argument et ne retourne rien.
    Il me semble que ton point de vue est très clair. Mais cependant, tu omets quelque chose d'après moi. J'ai mis beaucoup de chose en citation car ça correspond à ce à quoi je vais répondre.

    Le développeur qui écrit le tri doit savoir de toute façon sur quelle entité il travaille que ce soit en OO ou en procédurale. Il y aura toujours une partie qui triera les listes, une les tableaux, une les hashmaps etc. C'est l'endroit où la tâche va être remplie qui change. Ainsi si en objet on avait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Class Container {
       tri () { — virtuel — }
    }
    Class Liste hérite de Container {
        tri () { — triage d'une liste — }
    }
    Class Tableau hérite de Container{
       tri () { — triage d'un tableau — }
    }
    en procédural on aurait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    trier_liste(l) { — triage d'une liste — }
    trier_tableau(t) { — triage d'un tableau — }
    tri (container c) { si c est une Liste alors trier_liste(c)
                        si c est un Tableau alors trier_tableau(c)
                        etc. }
    ou avec de la surcharge
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    tri(l:Liste) { — triage d'une liste — }
    tri(t:Tableau) { — triage d'un tableau — }
    Dans ce cadre, le développeur qui crée cette bibliothèque doit savoir la même chose qu'il soit en OO ou en procédural. Dans la deuxième version on s'affranchit des noms différents pour les procédures et on bénéficie d'une transparence dans l'utilisation aussi.

    Citation Envoyé par Tommy31 Voir le message
    En langage objet tu peux écrire une fonction de tri (une méthode statique)unique qui s'applique sur n'importe quel type de collection, pour peu quelle obéisse à un comportement prédéfini.

    Ainsi, je peux écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      Tableau a;
      ListeChainee b;
    
      Util.tri(a)
      Util.tri(b)
    En procédural, tu ne peux pas, tu es obligé d'écrire plusieurs fonctions de tri, une adaptée à chaque type de collection.
    Les méthodes statiques sont un « truc » ajoutés dans l'OO mais qui ne sont pas du pur OO. C'est du procédural en fait car la méthode devient une fonction universelle dans le sens où c'est exactement elle et non une méthode propre à chaque objet qui est utilisée. Et dans le sens où tu l'as écris on peut justement le faire en langage procédural avec l'exemple que je fournissais au dessus en réponse à Alex_pi.

    Là par contre où je rencontre Alex_pi c'est quand on va parler de la version « pour l'utilisateur » et non celle du développeur:
    Citation Envoyé par alex_pi Voir le message
    Et la notation a un sens. Quand on écrit monObjet.tri(), on appelle la méthode tri spécifique à l'objet. On n'a aucun besoin de savoir quel type d'objet c'est, juste qu'il dispose d'une méthode tri. Ca peut être une liste, un tableau, autre chose, peu importe. Le choix du code réellement exécuté se fait dynamiquement, mais de façon transparente au programmeur, et sûre.
    En revanche, quand on écrit tri42(monElement), il faut être sur que monElement est bien du type attendu par la procédure tri42, ce qui n'a rien à voir. Il n'y a qu'une seule procédure portant le nom tri42, et il ne faut pas se planter, sinon, boom.[...].
    Effectivement, l'utilisateur dans le procédural doit, en général, connaître le type de l'entité et s'assurer a priori qu'il a le bon. Je dis a priori, car rien n'empêche d'avoir un surtype général qui serait utilisable... comme les pointeurs sur void ou qu'il n'y ait pas de typage et uniquement donc une précondition à respecter, comme on aurait en Scheme où on demanderait que le type soit triable. À ce moment, la fonction en procédural pourrait lancer une erreur à la compilation de la même manière que le compilateur dirait que telle ou telle méthode n'existe pas, ou encore une exception durant le cours du programme (et qu'on me dise pas que les exceptions sont OO c'est faux: ce sont des continuations qui viennent du paradigme fonctionnel, c'est pas Alex_pi qui va me contredire je pense). Donc, oui a priori, le programmeur qui utilise l'objet va sentir une utilisation plus souple parce que les langages procéduraux n'ont pas de surtype général qu'on pourrait appeler Data par exemple . Ce n'est pas une contradiction avec le paradigme. Et bien sûr, il y a la surcharge qui peut complètement cacher le problème des noms.

    Le programmeur qui développe les modules ou les classes lui, ne voit finalement pas de différence: soit il dispatche le code pour le rapprocher de l'entité; soit il le regroupe dans une seule place. Il y a des pours et des contres pour chaque cas. Personnellement, je ne me prononce pas sur ça. Les premiers arguments pour l'OO de l'ordre dont nous discutons ici car les tenants du procédural l'auraient vite démonté. Les premiers arguments qui touchèrent les développeurs étaient dans les problèmes de maintenance. Car un des problèmes de regrouper le code d'après les fonctionnalités et non les données est que la modification d'une entité impose la modification de nombreuses fonctions réparties souvent dans des modules distincts. C'est ça qui a été le fer de lance des arguments. Je rappelle que la maintenance c'est en moyenne 70% du coût total d'un logiciel. Ça touchait le cœur des décideurs — et par cœur je veux dire porte-monnaie bien sûr Mais là encore, tout le monde n'est pas d'accord. Grammatici certant.

    Au final, j'ai surtout l'impression que ce qui est mis en avant ici comme un avantage de l'OO est plus dû à une question de typage et de surtype qu'autre chose.

  15. #95
    Membre chevronné

    Homme Profil pro
    Architecte logiciel
    Inscrit en
    Novembre 2006
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte logiciel
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 252
    Points : 1 954
    Points
    1 954
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    qsort ( a ...);
    qsort ( b ...);
    Désolé. T'es obligé de l'écrire 2 fois avec surcharge, car le 1er argument n'accepte qu'un tableau, pas une liste chainée par exemple.

    Citation Envoyé par souviron34 Voir le message
    Et je ne vois pas comment un langage objet pourrait deviner sur quel élement il doit faire le tri ni comment... Un tri ascendant sur des flottants ou sur une chaîne de caractère c'est pas la même chose... de même que sur des entiers ou les jours des mois (qui se resettent à chaque fin de mois)
    Justement, l'info est portée par l'objet lui même, et c'est ce qui fait toute la différence. L'objet collection qui est trié expose le comportement permettant sa manipulation, et les objets contenus la façon de se comparer entre eux.

  16. #96
    Membre chevronné

    Homme Profil pro
    Architecte logiciel
    Inscrit en
    Novembre 2006
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte logiciel
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 252
    Points : 1 954
    Points
    1 954
    Par défaut
    Citation Envoyé par Garulfo Voir le message
    Les méthodes statiques sont un « truc » ajoutés dans l'OO mais qui ne sont pas du pur OO.
    Rien ne m'empêche d'en faire un objet pur pour bénéficier du polymorphisme. J'avais déjà donné cette solution pour traiter les variétés d'algorithme de tri.

    Citation Envoyé par Garulfo Voir le message
    C'est du procédural en fait car la méthode devient une fonction universelle dans le sens où c'est exactement elle et non une méthode propre à chaque objet qui est utilisée. Et dans le sens où tu l'as écris on peut justement le faire en langage procédural avec l'exemple que je fournissais au dessus en réponse à Alex_pi.
    Non, car tu écris PLUSIEURS fonctions surchargées. Moi je n'en écris qu'UNE.

  17. #97
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    Je ne connais rien à Ocaml, à la limite je peux lire du C++ ou du Pascal Object..
    J'ai utilisé OCaml parce que c'est beaucoup moins verbeux et bien plus souple, mais je me doutais bien que ça n'allait pas me servir puisque personne n'arriverait à lire


    Citation Envoyé par souviron34 Voir le message
    Maintenant voici ce que je ferais :

    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    typedef struct pObjet {
        int Type ;
        int x  ;
        int y ;
        int width ;
        int height ;
    } Objet ;
    
    #define RECT 0
    #define ELLIP 1
    ....
    
    Objet MesObjs[2] ;
    Widget Image ; /* Par exemple, n'importe quel objet de style graphique */
    
    
    MesObjs[0].Type = RECT ;
    MesObjs[1].Type = ELLIP ;
    
    for ( i = 0 ; i < 2 ; i++ )
    {
       MesObjs[i].x = 100 + i*100 ;
       MesObjs[i].y = 100  ;
       MesObjs[i].width = 80 ;
       MesObjs[i].height = 50 ;   
    } 
    
    ...
    
    Get_Mouse ( Image, &posx, &posy ),
    Select_Objet (MesObjs, posx, posy );
    ..
    
    
    void Select_Objet ( Objets *LesObjets, int x, int y ) /* x, y position souris */
    {
       Objet CetObj ;
    
       Get_Select (LesObjets, x, y, &CetObjet);
    
       Draw_Enhanced ( &CetObjet );
    }
    
    
    void Draw_Enhanced ( Objet *ObjetATracer )
    {
        switch ( ObjetATracer->Type )
         {
            case ELLIP ;
                   XDrawArc () ... ; /* avec X11, ou GTKDraw.. si ça existe */
                   break ;
             case RECT :
                   XDrawRect ()... ; /* avec X11, ou GTKDraw.. si ça existe */
                   break ;
         } 
    }
    En gros, bien sûr...
    [/CODE]
    Pour moi, les problèmes de ce code sont nombreux.
    • Tu partages exactement la même structure entre tous les objets "imprimables". Quid du polygone, qui n'a pas deux dimensions, mais est une liste de points ? Tu dois tout modifier pour les accepter.
    • Ce n'est absolument pas typé (mais bon, en même temps, c'est du C). Le compilo ne peut rien vérifier pour toi, puisque tout à le même type et qu'il n'y a qu'un encodage arbitraire du type dans un entier (d'ailleurs, il n'y a pas "enum" en C, qui permettrait d'éviter d'avoir à définir cette macro ??), et qu'il faut ensuite caster sauvagement en croisant les doigts qu'on ne s'est pas tromper. Pour une bibliothèque bien testé, mouais. Pour du code "normal", bonjour les dégats (oui oui, il "suffit" de savoir ce qu'on fait et de faire attention.. Mais si en plus on a un compilo qui nous donne le feu vert, c'est quand même pas plus mal)
    • Ca ne passe pas à l'échelle. Si je veux à la fois avec des objets imprimable (par exemple des rond, des carrés) et des objets triables (par exemple des tableaux, des listes), je suis obligé d'écrire une fonction de dispatch pour chaque. Supposons maintenant que je veuille qu'une image, qui est une liste d'objets imprimables soit aussi un objet triable (par exemple, on ordonne les sous image par rapport à la distance à un point). Il faut maintenant partager les types entre ceux qui sont "imprimables" et ceux qui sont "triable", et hacker de la même façon les deux fonction de dispatch. Mais après, on a aussi les objets observables, les listeners, etc etc (je vous redirige vers la doc de java pour voir le nombre impressionnant d'interfaces auquel on peut penser)
    • Ce n'est pas dutout modulaire. Si j'ai par exemple deux librairies indépendantes, qui toutes les deux fournissent une interface "Serialisable", avec une méthode "to_string": dans ton modèle, chacune des librairies doit proposer sa propre liste de types encodés par des entier, et sa propre fonction de dispatch qui reçoit un de ses propre type et l'envoie vers la bonne fonction de serialisation. En revanche, tu ne peux pas mélanger naturellement les objets des deux librairies, à moins de les empaqueter dans une pair dont le premier élément serait la librairie d'origine, et d'écrire une fonction de dispatch qui selon la librairie d'origine appellerai à son tour la fonciton de dispatch adapté... Ca devient lourd ! En objet, pas de problème, on peut mélanger les deux types, et simplement appeler notre méthode "to_string" sans se préoccuper d'où ils viennent.



    Citation Envoyé par souviron34 Voir le message
    PS 1: je ne dis pas que c'est forcément mieux, mais que (à part peut-être avec OCaml dont on a déjà discuté et dont la syntaxe m'apparaît plus qu'obscure), pour des langages objets "courants", je ne pense pas que coder l'équivalent soit plus léger...
    Sur un exemple minimaliste, on a peut être un volume équivalent de code, mais comme je dis plus haut, je ne pense pas que ton approche passe aussi facilement à l'échelle que l'approche objet

    Citation Envoyé par souviron34 Voir le message
    PS 2 : tu as à peu près le même nombre de lignes que moi, et pour tes additions de surface ou tes calculs, il te faut bien les coder... Car ton .add recouvre bien du code quelque part...
    En l'occurrence, le code que j'ai donné est complet et compile tel quel, en donnant les surface, etc. Mais bon, ce n'est pas non plus franchement un exemple réaliste

  18. #98
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par Garulfo Voir le message
    Le développeur qui écrit le tri doit savoir de toute façon sur quelle entité il travaille que ce soit en OO ou en procédurale. Il y aura toujours une partie qui triera les listes, une les tableaux, une les hashmaps etc. C'est l'endroit où la tâche va être remplie qui change.
    Je suis parfaitement d'accord qu'à ce niveau là, la quantité de code est la même.

    Citation Envoyé par Garulfo Voir le message
    en procédural on aurait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    trier_liste(l) { — triage d'une liste — }
    trier_tableau(t) { — triage d'un tableau — }
    tri (container c) { si c est une Liste alors trier_liste(c)
                        si c est un Tableau alors trier_tableau(c)
                        etc. }
    ou avec de la surcharge
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    tri(l:Liste) { — triage d'une liste — }
    tri(t:Tableau) { — triage d'un tableau — }
    Il me semble quand dans les langages que je connais, quand il y a surcharge, elle doit être résolue statiquement, c'est à dire que le compilo choisi une fois pour toute à la compilation quelle fonction sera appelé. Si ça se passe à l'exécution, on retombe sur du dispatch dynamique, et là, on retombe globalement sur de l'objet ! Sauf qu'au lieu d'avoir le dispatch au niveau de chaque objet, on l'a au niveau de chaque fonction. Et là effectivement, c'est assez dual. Sauf que ça ne passe pas la barrière des modules !


    Dans ce cadre, le développeur qui crée cette bibliothèque doit savoir la même chose qu'il soit en OO ou en procédural. Dans la deuxième version on s'affranchit des noms différents pour les procédures et on bénéficie d'une transparence dans l'utilisation aussi.
    Justement, ce qui me chagrine ici, c'est qu'on suppose qu'on a une librairie, et une seule. Si je veux écrire une librairie qui a juste besoin d'un conteneur triable, lui même implémenté dans une autre librairie non connue a priori, avec cette fonction de dispatch non a priori connu, on est mal partie
    (Oui, dans un langage fonctionnel, on peut passer la fonction, et dans un langage à la ML, on peut faire un foncteur, mais ce n'est pas vraiment du "procédural" de base). C'est ça qui fait la puissance de l'objet je pense, de proposer des interfaces claires qui peuvent être partagé entre différentes librairies et être utilisés de façon aveugle.


    Là par contre où je rencontre Alex_pi c'est quand on va parler de la version « pour l'utilisateur » et non celle du développeur:
    Le problème est que l'utilisateur d'une librairie a de bonne chance d'être le développeur d'une autre librairie



    Les premiers arguments pour l'OO de l'ordre dont nous discutons ici car les tenants du procédural l'auraient vite démonté. Les premiers arguments qui touchèrent les développeurs étaient dans les problèmes de maintenance. Car un des problèmes de regrouper le code d'après les fonctionnalités et non les données est que la modification d'une entité impose la modification de nombreuses fonctions réparties souvent dans des modules distincts. C'est ça qui a été le fer de lance des arguments. Je rappelle que la maintenance c'est en moyenne 70% du coût total d'un logiciel. Ça touchait le cœur des décideurs — et par cœur je veux dire porte-monnaie bien sûr Mais là encore, tout le monde n'est pas d'accord. Grammatici certant.
    Au final, j'ai surtout l'impression que ce qui est mis en avant ici comme un avantage de l'OO est plus dû à une question de typage et de surtype qu'autre chose.
    Effectivement, ce qui se vend bien, c'est le fait que c'est maintenable, mais la raison profonde, c'est justement qu'on peut séparer les endroits où ont lieux les implémentation, ce qui rend les programmes beaucoup plus modulaire, et donc chaque partie est moins sensible aux modification sur les autres parties. Donc oui, parler de sous typage n'est pas la façon la plus vendeuse de présenter la chose, mais je suis personnellement raisonnablement persuadé que c'est en fait ça qui fait que les arguments vendeurs sont vrais.

  19. #99
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 279
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 279
    Points : 11 015
    Points
    11 015
    Par défaut
    Citation Envoyé par alex_pi Voir le message
    Mais ce n'est pas du procédural, c'est de l'objet avec une syntaxe différente... C'est toi qui te focalise de façon complètement hors sujet sur la syntaxe...
    Ce n'est pas moi qui dit que (f e) et (e f) ne sont pas des écritures duales.
    -> "puisque pour le procédural, on fait (f e) en appelant une procédure sur un objet, et dans l'autre on fait (e f) en appelant la procédure d'un objet."
    Vision que je trouve syntaxique, et limitative: quid des contravariances qui font que l'opération exacte se retrouvant exécutée est fonction des paramètres, et pas juste en fonction du type réel de l'objet "possédant" l'opération.


    Citation Envoyé par Tommy31 Voir le message
    En langage objet tu peux écrire une fonction de tri (une méthode statique)unique qui s'applique sur n'importe quel type de collection, pour peu quelle obéisse à un comportement prédéfini.
    une adaptée à chaque type de collection.
    C'est exactement la même chose en OO, à un moment où un autre, il est nécessaire d'introduire un point de variation. Et à ce point, plusieurs fonctions de presque même nom devront exister. Que la fonction s'appelle trier_toto ou Toto::trier ne change pas grand chose au final.
    (Bien sûr le point de variation n'est pas nécessairement au niveau de la fonction de tri, il peut être relégué au niveau des itérateurs selon qu'ils supportent les accès directs, ou juste les accès séquentiels bi-directionnels ; mais c'est un détail)
    Côté utilisateur, un polymorphisme paramétrique (qui n'a rien d'OO) suffira pour appeler la bonne fonction (cf les cours d'algorithmique de Stepanov qui ne sont malheureusement plus en ligne avec l'arrivée imminente du bouquin), ou un semblant d'introspection. Autre débat, un langage procédural, non OO, non générique, mais qui dispose d'une once d'introspection (j'ai au moins un exemple: le VimL), peut-il toujours être considéré comme procédural et juste procédural ?



    PS: si c'est juste pour dire que l'OO apporte le polymorphisme d'inclusion (accessoirement dynamique), oui c'est clair, c'est sa grande force. Ou alors c'est pour illustrer la vision "message" ? Et là, vous aurez vite vu que je n'y accorde pas la moindre importance. ^^'

  20. #100
    alex_pi
    Invité(e)
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Ce n'est pas moi qui dit que (f e) et (e f) ne sont pas des écritures duales.
    -> "puisque pour le procédural, on fait (f e) en appelant une procédure sur un objet, et dans l'autre on fait (e f) en appelant la procédure d'un objet."
    Vision que je trouve syntaxique,
    La syntaxe est là pour nous aider à parler de la même chose, pas pour en déduire des choses. Alors ce que je comprends pour chaque syntaxe est :
    f e : Je choisi statiquement (à la compilation) une fonction f et je l'applique à e, et ce quelque soit e.
    e.f (ou e#f à la OCaml) : j'ai dynamiquement un objet e, et j'appelle *sa* méthode f. Et si on veut le noter (e f), il faut bien préciser qu'ici f n'est pas une fonction prise en argument mais un symbole, un nom de fonction, et que l'objet l'utilise pour choisir en interne laquelle de ses méthodes il va choisir. En Scheme, c'est sans doute possible, dans les autres langage, c'est probablement plus difficile.


    et limitative: quid des contravariances qui font que l'opération exacte se retrouvant exécutée est fonction des paramètres, et pas juste en fonction du type réel de l'objet "possédant" l'opération.
    Pour moi la contravariance, c'est ce qui fait que quand A est inclus dans B, alors B -> int est inclu dans A -> int. Donc je ne vois pas le rapport. Qu'est ce que tu entends par contravariance ?


    Côté utilisateur, un polymorphisme paramétrique (qui n'a rien d'OO) suffira pour appeler la bonne fonction (cf les cours d'algorithmique de Stepanov qui ne sont malheureusement plus en ligne avec l'arrivée imminente du bouquin)
    Alors là j'aimerais bien voir ça ! Parce que si tu ne mets aucune contrainte sur ton type d'entrée, tu l'as un peu dans l'os... Et si ta contrainte est "contient une méthode tri", alors c'est du polymorphisme d'inclusion

    ou un semblant d'introspection. Autre débat, un langage procédural, non OO, non générique, mais qui dispose d'une once d'introspection (j'ai au moins un exemple: le VimL), peut-il toujours être considéré comme procédural et juste procédural ?
    <troll>Je pense qu'on peut surtout dire que c'est un langage avec un mauvais design qui a besoin de hacks sordides pour s'en sortir avec des casts sauvages</troll>

+ Répondre à la discussion
Cette discussion est résolue.
Page 5 sur 12 PremièrePremière 123456789 ... DernièreDernière

Discussions similaires

  1. Avantages et inconvénients par rapport au C++ ?
    Par clovis dans le forum Smalltalk
    Réponses: 3
    Dernier message: 11/07/2009, 17h58
  2. les avantages d'PHPEclipse par rapport aux autres IDE php
    Par young077 dans le forum Eclipse PHP
    Réponses: 2
    Dernier message: 29/08/2007, 10h09
  3. avantage win vista par rapport à win Xp
    Par young077 dans le forum Windows Vista
    Réponses: 32
    Dernier message: 08/08/2007, 19h22
  4. Réponses: 1
    Dernier message: 14/08/2006, 19h02
  5. [VB6] Avantage de DAO par rapport à ADO
    Par crazyyann dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 17/06/2004, 07h48

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