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

Débats sur le développement - Le Best Of Discussion :

[Débat] C++ vs Java


Sujet :

Débats sur le développement - Le Best Of

  1. #1801
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : août 2005
    Messages : 2 894
    Points : 7 197
    Points
    7 197
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    a- Tu te trompes. Les choses ont bien changé.
    Nous avons quantité de bibliothèques qui nous assurent la portabilité du code métier. Et elle est de qualité équivalente à ce qui ce passe en java (aujourd'hui -- il y a eu des progrès depuis le coup de gueule de RSM pour OOo) quand on change de compilo ou même de version de VM & co.
    Pour les libs, nous avons aussi des outils magiques comme cmake qui s'occupent de tout pour nous -- même si pas encore parfait, c'est un excellent début.
    J'ai hélàs pas d'expérience en C++. Cependant j'émet un doute sur la portabilité des .o, .so et .dll.
    Concernant ces bibliothèques, elles sont codées avec des instructions préprocesseurs ou elles utilisent des .h génériques couplés à des .cpp spécifiques ou autre ? Parce que dans ce cas, soit tu considères que tu as déportés le problème, soit tu considères que tu utilises une VM ...

    Citation Envoyé par Luc Hermitte Voir le message
    b- S'il n'y a que ça qui compte, autant coder dans des langages interprétés ...
    Ce n'est pas pour rien qu'on parle de langage semi-interprété ou semi-compilé (c'est comme le verre à moitié plein, à moitié vide).
    Ensuite les langages interprétés n'ont pas vérifications statiques du code dans sa globalité et de pré-transformation pour accélérer la transformation en code binaire à l'exécution. Ces étapes sont effectuées à chaque exécution du programme et perdues à la fin de celui-ci. Ce qui conduit à ce qu'une ligne de code soit toute pourrie mais jamais contrôler tant qu'elle n'est pas exécutée.

    Ensuite en Java on est très adepte des librairies tierces, et ne pas avoir à les recompiler à chaque fois est une chose non négligeable.


    Citation Envoyé par Luc Hermitte Voir le message
    c- On y perd le NVI avec l'interdiction. C'est cher payer la présomption d'incompétence.
    En Java j'ai rarement ressenti un tel besoin qui d'ailleurs tend faire à confondre héritage et composition. Mais j'avoue en avoir parfois ressenti le besoin.
    Par ailleurs, il y un pattern assez connu pour contourner le problème en utilisant la composition. Ensuite preuve de ce manque, Java a vu émergé les annotations et la programmation par aspet.
    Il s'agit en fait d'injecter de l'appel à du code factorisé dans un coin directement dans les classes semi-compilées. Ce qui revient à automatiser le premier contournement dont je faisais mention.

    Donc il existe bien un contournement, certes pas élégant à ce problème.

    D'ailleurs, il serait intéressant de voir comment les autres langages qui ont fait le même choix s'en sortent.

    Citation Envoyé par Luc Hermitte Voir le message
    d- La base c'est bien le LSP. -> Principe de Substitution de Liskov
    Le choix des mots n'est pas un hasard chez nous. Trop souvent on voit de l'héritage utilisé à tord parce que le LSP n'a pas été compris (cf carrés & rectangles, listes et listes triées, etc). Polymorphisme [Accessoirement, un concept plus général et bien antérieur à l'OO.] est un mot qui est souvent très mal assimilé, il suffit de voir les tentatives d'explication qui trainent à base de "prend plusieurs formes" qui ne veulent strictement rien dire.
    Merci pour ce petit cours J'aurais bien aimé que mes profs me présentent les choses de cette manière ; ils n'ont jamais évoqué le Liskov.

    Si je résume bien, cela dit qu'un contrat fixé par un type est valable pour tous les sous-types ? Dommage et heureusement que la programmation par contrat (pré-condition/post-condition) n'existe pas vraiment en Java ... Ca m'arrive de contourer ce principe Mais c'est peut-etre à cause de code mal fichu à la base ...

    Citation Envoyé par Luc Hermitte Voir le message
    e- Aux dernières nouvelles int ou les tableaux ne sont pas des objets en Java. En Ruby j'aurai été d'accord.
    Tout est affaire de pragmatisme et plus particulièrement d'optimisation dans ce cas. Et ce n'est pas pour rien qu'ils ont leur wrapper.

    Citation Envoyé par Luc Hermitte Voir le message
    f- Pour que ce problème se pose, c'est que le LSP n'a pas été correctement appliqué. [je ne fais que paraphraser Koala]
    J'attendrai ta confirmation sur mon interprétation du LSP.

    Citation Envoyé par Luc Hermitte Voir le message
    g- Il y a des limites. Typiquement dans les lib mathématiques. Rattacher les fonctions trigo à des objets n'a pas de sens. D'ailleurs ce n'est pas le cas, c'est juste rattaché à classes qui servent alors d'espaces de noms. Sauf qu'ils ne sont pas extensibles.
    Tu as un concet de fonction trigo, non ? Donc d'un point de vue OO, un type "Fonction trigonométrique".

    Citation Envoyé par Luc Hermitte Voir le message
    h- même un int ?
    Désolé, elle était facile.
    Plus sérieusement. Koala (arrête moi si je me trompe) critiquait que la clé n'impose pas précisément le type attendu, et que donc on peut avoir une map à clés hétérogènes. Les générics corrigent ça, mais c'est juste un sucre syntaxique et il est toujours nécessaire d'avoir une fonction de comparaison qui doit assumer qu'il peut y avoir eu un cas foireux dans le code et donc tester à l'exécution que les types sont bien comparables -- cf toutes les digressions qui ont suivi.
    Là où le typage du C++ nous aurait envoyé ballader dès la compilation.
    Oui, via son wrapper Integer.
    Le choix d'utiliser Object (notemment pour les méthodes get et delete) sont là pour éviter les cast qui ne sont pas nécessaires ; et qui peuvent être couteux (type checking) si on sait d'un objet tel qu'une map peut être souvent sollicité dans un programme. Encore et toujours affaire de pragmatisme.

    Si tu prends le cas d'une Reference Map, elle permet de créer une association non pas entre des clés mais bel et bien des instances (comprendre que la clé c'est l'adresse mémoire). Dans ce cas tu te retrouves bien avec des clés totalement hétérogène. Le but de toutes façons n'est pas d'avoir des clés hétérogènes mais de traiter les Hash map (quelque soit la nature de leurs clés) de manière unique. De la généricité quoi.

    J'avoue que les generics c'est un peu bidon mais pour te rassurer il existe les "checked collections". Et les "templates" ne sont pas la panacée car chaque "type" regénère du binaire supplémentaire. Et une question, deux "type" d'un même template avec les mêmes paramètres génériques sont-ils substituables ? En gros est-ce que deux déclarations de List d'entier sont substituables ? Si oui, est-ce toujours vrai pour une Liste de voiture et une liste de véhicule ?

    Concernant la vérification à la compilation elle n'est valable que si tes listes sont bien spécifiques mais dès que tu en veux des génériques ... T'as le même problème.

    Citation Envoyé par Luc Hermitte Voir le message
    i- void* et le superobject sont décriés en C++.
    Et C++ a pris la voie des concepts -- même si on n'a pas su les mettre en oeuvre proprement -- trop d'historique et pas assez de temps je crains. Je renvoie de nouveau à la video de Stépanov.
    Pourquoi ne pas le faire si c'est nécessaire ?
    Si je prends une classe assez con : les ensembles. Ton idée ca serait de faire une classe SetElement ? Idem pour les clés d'une map avec MapKey ? Dans ce cas, je pense que finalement Java n'a pas tant de wrapper que ça ...

    Citation Envoyé par Luc Hermitte Voir le message
    k- et ?
    Bah s'ils ont pas de racine commune tu te retrouves ni plus, ni moins qu'avec des void* ! Mais sans comportement commun.

    Citation Envoyé par Luc Hermitte Voir le message
    l- Tout pareil :p
    Pas de soucis C'est juste que je suis pleinement conscient que ma manière de m'exprimer est agressive. Mais il faudrait plutôt voir toutes mes phrases avec des points d'interrogations ;-)
    Je suis un développeur C++ contrarié et je suis preneur d'un point de vue honnête, complet, sérieux sur ce langage qui me semble bien mieux que Java mais dont hélàs les opportunités sont plus réduites et que mon parcours professionnel témoigne énormément en ce sens (un peu plus d'un an en Cobol et environ 3 en Java).
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  2. #1802
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : juin 2002
    Messages : 2 165
    Points : 4 605
    Points
    4 605
    Par défaut
    Citation Envoyé par Nemek Voir le message
    En Java j'ai rarement ressenti un tel besoin qui d'ailleurs tend faire à confondre héritage et composition.
    Et tu n'implémentes jamais plusieurs interfaces ?
    Pour revenir à la possible confusion héritage et composition, c'est justement là qu'intervient le LSP.

    Citation Envoyé par Nemek Voir le message
    D'ailleurs, il serait intéressant de voir comment les autres langages qui ont fait le même choix s'en sortent.
    Le D, sur lequel je planche des derniers temps, a fait le choix d'interdire l'héritage multiple mais d'autoriser l'implémentation de plusieurs interfaces comme Java mais propose également :
    • Des interfaces plus riches permettant d'implémenter le NVI (il est possible d'avoir des méthodes finales non abstraites dans ces interfaces).
    • Un support de la PpC.

    Ce qui couvre la très grande majorité des recours à l'héritage multiple (en tout cas la totalité des miens).

  3. #1803
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : juin 2003
    Messages : 4 506
    Points : 5 606
    Points
    5 606
    Par défaut
    Citation Envoyé par gl Voir le message
    .


    Le D, sur lequel je planche des derniers temps, a fait le choix d'interdire l'héritage multiple mais d'autoriser l'implémentation de plusieurs interfaces comme Java mais propose également :
    • Des interfaces plus riches permettant d'implémenter le NVI (il est possible d'avoir des méthodes finales non abstraites dans ces interfaces).
    • Un support de la PpC.

    Ce qui couvre la très grande majorité des recours à l'héritage multiple (en tout cas la totalité des miens).
    Ce que tu cites, et vu rapidement en faisant une recherche sur le net, sur les interfaces en D est vraiment intéressant. Cela semble être un bon compromis après avoir concédé l'héritage multiple.

    C'est vraiment un manque qui existe notamment en C# puisque je ne pratique pas Java mais cela doit manquer aussi à Java sûrement. Peut-être que cela se verra dans la sortie de prochaines versions de ces langages ?

    Quand au support de la PpC là encore en C# il y a code contract qui permet de faire de la vérification statique et dynamique de code à contrario du C++ ou Java qui de ce que je sais permet de vérifier des contrats surtout de manière dynamique soit à l’exécution (quoique en C++ j'ai un doute avec toute cette méta programmation générique...)

    Ps : C# n'est pas vraiment le sujet mais bon c'est juste pour noter que la vérification des contrats dont on parle là en C++ ou Java voir même en D sont des vérifications dynamiques soit à l’exécution, en tout cas d'après ma pauvre connaissance sur ces langages. Donc quid de la vérification avant l'exécution (signalement à la compilation d'une 'potentielle' ou violation de contrats ?) ?
    " Dis ce que tu veux qui insulte mon honneur car mon silence sera la réponse au mesquin.
    Je ne manque pas de réponse mais : il ne convient pas aux lions de répondre aux chiens ! " [Ash-Shafi'i ]

  4. #1804
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    octobre 2004
    Messages
    11 511
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : octobre 2004
    Messages : 11 511
    Points : 29 908
    Points
    29 908
    Par défaut
    Citation Envoyé par Nemek Voir le message
    J'ai hélàs pas d'expérience en C++. Cependant j'émet un doute sur la portabilité des .o, .so et .dll.
    Concernant ces bibliothèques, elles sont codées avec des instructions préprocesseurs ou elles utilisent des .h génériques couplés à des .cpp spécifiques ou autre ? Parce que dans ce cas, soit tu considères que tu as déportés le problème, soit tu considères que tu utilises une VM ...
    Il faut avouer que ce n'est, effectivement pas du "compile once, run everywhere" mais il est tout à fait possible d'arriver à une compatibilité parfaite en s'astreignant à des règles de codage simplement "correctes".

    Il ne faut pas oublier que tu n'arriveras de toutes manières pas non plus à faire tourner la version "windows" de la JVM dans un environnement *nux !!

    Mais, par contre, je suis actuellement sur un projet utilisant près de 2000 classes, dont une partie est écrite exclusivement en C++ "standard" (avec un peu de boost cependant ) et dont une autre partie utilise Qt .

    Je peux t'assurer que l'on compte les endroits où l'on a recours à la compilation conditionnelle (par exemple pour déterminer le système sur lequel on travaille) sur les doigts d'une main, et que cela n'a rien à voir avec l'utilisation de bibliothèque, mais plutot avec l'impossibilité de trouver une application particulière ( excel pour ne pas la citer) sur des machines *nux
    Ce n'est pas pour rien qu'on parle de langage semi-interprété ou semi-compilé (c'est comme le verre à moitié plein, à moitié vide).
    Ensuite les langages interprétés n'ont pas vérifications statiques du code dans sa globalité et de pré-transformation pour accélérer la transformation en code binaire à l'exécution. Ces étapes sont effectuées à chaque exécution du programme et perdues à la fin de celui-ci. Ce qui conduit à ce qu'une ligne de code soit toute pourrie mais jamais contrôler tant qu'elle n'est pas exécutée.
    j'ai presque envie de dire "mais pourquoi faire le travail à moitié "

    Bon, c'est très mauvais...
    Ensuite en Java on est très adepte des librairies tierces, et ne pas avoir à les recompiler à chaque fois est une chose non négligeable.
    En C++ aussi on est adepte des bibliothèques (hé oui, la traduction de library, c'est... bibliothèque ) tierces

    Et ce n'est pas cela que l'on recompile à chaque fois
    En Java j'ai rarement ressenti un tel besoin
    Tant mieux pour toi
    qui d'ailleurs tend faire à confondre héritage et composition.
    Le fait est que, bien souvent, "l'héritage mal conçu" (comprend: ne respectant pas LSP ) serait souvent bien avantageusement remplacé par une composition

    Mais l'énorme avantage du NVI est qu'il permet de fournir des "points de variation" de manière particulièrement fine...

    Cela permet de respecter d'avantage encore un conseil issu de l'XP: DRY (Don't repeat Yourself ) en évitant, justement, d'obliger la personne qui veut dériver une de nos classes à devoir... reprendre le code de la classe parente pour les parties de variant pas
    Mais j'avoue en avoir parfois ressenti le besoin.
    Par ailleurs, il y un pattern assez connu pour contourner le problème en utilisant la composition. Ensuite preuve de ce manque, Java a vu émergé les annotations et la programmation par aspet.
    Il s'agit en fait d'injecter de l'appel à du code factorisé dans un coin directement dans les classes semi-compilées. Ce qui revient à automatiser le premier contournement dont je faisais mention.

    Donc il existe bien un contournement, certes pas élégant à ce problème.
    Si tu le reconnais toi même...

    Mais j'irais même plus loin: ca rend, pour moi, l'utilisation d'un bazooka obligatoire pour chasser une mouche Pas vrai
    D'ailleurs, il serait intéressant de voir comment les autres langages qui ont fait le même choix s'en sortent.
    Surement de manière similaire
    Merci pour ce petit cours J'aurais bien aimé que mes profs me présentent les choses de cette manière ; ils n'ont jamais évoqué le Liskov.
    Pourquoi l'aurait il évoqué dans un cours de java, alors que tout dans java tend à minimiser l'importance de ce principe, alors que c'est (en réalité) le premier de tous
    Si je résume bien, cela dit qu'un contrat fixé par un type est valable pour tous les sous-types ?
    Ou du moins que la marge de manoeuvre des sous-types concernant le contrat est fortement limitée:
    1. Les préconditions ne peuvent pas être renforcées dans le sous type
    2. Les postconditions ne peuvent pas être allégées dans le sous type
    3. Les invariants du type de base doivent etre respectés dans le sous type.

    Dommage et heureusement que la programmation par contrat (pré-condition/post-condition) n'existe pas vraiment en Java ... Ca m'arrive de contourer ce principe Mais c'est peut-etre à cause de code mal fichu à la base ...
    Il y a des chances que ce soit à cause de cela, en effet

    Mais, à ta décharge, cela peut remonter vraiment haut, comme à l'obligation qui t'est faite d'hériter, en toutes circonstances, de la classe Object.

    Pour ma part, je trouve quelque part presque dommage que la programmation par contrat ne soit pas plus mise en avant... Cela inciterait les gens à se poser les bonnes questions avant de décider qu'il est plus intéressant de recourir à l'héritage là où tout ce qui les intéresse, c'est de récupérer du code, sans être attentif à la "sémantique" de leur classe.
    Tu as un concept de fonction trigo, non ? Donc d'un point de vue OO, un type "Fonction trigonométrique".
    Est-ce une raison pour être obligé de les mettre dans une classe, quand on sait que toutes ces fonctions ont de grandes chances de devoir être statiques car pouvant potentiellement ne dépendre d'aucune instance de la classe :question (et tu sais tout le bien que je pense des fonctions statiques)
    Oui, via son wrapper Integer.
    Le choix d'utiliser Object (notemment pour les méthodes get et delete) sont là pour éviter les cast qui ne sont pas nécessaires ; et qui peuvent être couteux (type checking) si on sait d'un objet tel qu'une map peut être souvent sollicité dans un programme. Encore et toujours affaire de pragmatisme.

    Si tu prends le cas d'une Reference Map, elle permet de créer une association non pas entre des clés mais bel et bien des instances (comprendre que la clé c'est l'adresse mémoire). Dans ce cas tu te retrouves bien avec des clés totalement hétérogène. Le but de toutes façons n'est pas d'avoir des clés hétérogènes mais de traiter les Hash map (quelque soit la nature de leurs clés) de manière unique. De la généricité quoi.
    Le fait est que je peux concevoir que, dans un domaine particulier, l'on puisse avoir besoin d'une map avec des valeurs "particulièrement hétérogènes", et même que l'on puisse avoir besoin de clé "pas tout à fait identiques" (mais cependant "relativement proches")

    Par contre, ce que j'ai beaucoup de mal à accepter, l'aspect systématique de la chose qui apparait en java: même si l'on se dit qu'une map va utiliser le type X comme clé et les types dérivant de Y comme valeur, on n'est jamais à l'abri de l'éventualité que quelqu'un, quelque part dans le code, n'ait pas saisi correctement l'utilisation qui est faite de la map et décide d'utiliser le type A comme clé et le type B commme valeur (A et B n'ayant définitivement rien à voir avec X et Y, tu l'auras compris ), surtout si "pour ne pas te casser la tête", tu as décidé (car tu as le droit de le faire ) d'accepter que la fonction qui s'occupera d'ajouter les élément à ta map prennent des références sur Object tant pour la clé que pour la valeur

    Tu peux te mettre à l'abri de ce genre d'erreur par programmation, de préférence en choisissant le type correct pour les arguments, au pire, en vérifiant le type réel des arguments que tu obtiens dans la fonction d'insertion, mais il est "dommage, dirons nous" qu'un langage qui se prétend facile et sécurisant permette qu'un mauvais choix d'un coté et une mauvaise compréhension de l'autre permette à des catastrophes de survenir

    Si tu supprimes la super classe et que tu garde une série de hiérarchie clairement distinctes (et "fatalement" de taille limitée ), la possibilité de faire ce genre d'erreur se réduit de plus en plus, surtout si toutes tes hiérarchies de classes respectent scrupuleusement LSP
    J'avoue que les generics c'est un peu bidon mais pour te rassurer il existe les "checked collections". Et les "templates" ne sont pas la panacée car chaque "type" regénère du binaire supplémentaire.
    Tu as, effectivement, du code binaire qui est généré pour chaque type spécialisant un template...

    Mais c'est normal

    Après tout, quand on écrit en C++ une classe proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template <typename Type>
    c lass MaClass
    {
    };
    et qu'on l'utilise avec les types A, B, et C (tous les trois étant différent ) c'est, au niveau du binaire généré comme si on avait écrit les trois classes (la répétition de code en moins)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class MaClassA // cas particulier utilisant le type A
    {
    };
    class MaClassB // cas particulier utilisant le type B
    {
    };
    class MaClasseC // cas particulier utilisant le type C
    {
    };
    Et une question, deux "type" d'un même template avec les mêmes paramètres génériques sont-ils substituables ?
    oui:

    std::list <int> est substituable à std::list<int>
    En gros est-ce que deux déclarations de List d'entier sont substituables ?
    Si le type d'entier (int Vs unsigned int, short Vs unsigned short), oui, bien sur
    Si oui, est-ce toujours vrai pour une Liste de voiture et une liste de véhicule ?
    Non...

    C'est pour cela que les collections de la stl n'ont pas vocation à être dérivées

    Par contre, tu peux effectivement créer une liste de pointeurs sur Base et insérer un pointeur sur Derivee si Derivee hérite effectivement de Base

    Mais attention, nous sommes là dans un paradigme qui n'a rien à voir avec le paradigme OO, nous abordons le troisième paradigme utilisé par C++ qui est le paradigme générique (celui ou l'on ne sait pas encore le type de valeurs que l'on va utiliser, mais ou l'on sait par contre comment on va comment on va les utiliser )
    Concernant la vérification à la compilation elle n'est valable que si tes listes sont bien spécifiques mais dès que tu en veux des génériques ... T'as le même problème.
    Justement pas!!!

    Bien au contraire

    Chaque fois que tu vas instancier une classe template avec un type particulier, le binaire correspondant va être généré (en fait, le code de ta classe va être compilé en considérant que l'on utilise le type envisagé).

    Si tu instancie ta classe template avec dix types différent, les vérifications effectuées à la compilation seront effectuées... dix fois (une fois pour chaque type avec lequel ta classe template est instanciée)

    C'est d'ailleurs ce qui ralenti (à notre grand dam) tellement la compilation

    Pourquoi ne pas le faire si c'est nécessaire ?
    Si je prends une classe assez con : les ensembles. Ton idée ca serait de faire une classe SetElement ? Idem pour les clés d'une map avec MapKey ? Dans ce cas, je pense que finalement Java n'a pas tant de wrapper que ça ...
    L'idée de concept est en fait différente (et a été écartée afin de permettre une sortie "relativement rapide" de la dernière norme en date, pour tout dire )

    L'idée est de se dire "voilà, j'ai besoin d'un concept X" (mettons : le concept de "sérialisabilité" )

    et de continuer "Pour qu'un classe respecte ce concept, il faut qu'elle expose certaines fonctions dont le nom et la signature sont clairement identifiés" ( les fonctions write et read, par exemple, pour le concept de sérialisabilité )

    Pour terminer par "je vais donc vérifier (à la compilation ) que tout objet qui me sera transmis ici dispose bel et bien des fonctions ad-hoc"

    La notion de concept permet donc une vérification "orthogonale" de ton projet car il n'est pas du tout impossible que tu aies une classe SerializableX qui hérite de X ainsi qu'un autre SerializableY qui hérite de Y (mais sans qu'il n'y ait le moindre lien entre la classe X et la classe Y ) dont le seul point commun est d'exposer un certain nombre de fonctions portant le même nom et acceptant un nombre de paramètres identique
    Bah s'ils ont pas de racine commune tu te retrouves ni plus, ni moins qu'avec des void* ! Mais sans comportement commun.
    Ben non, pourquoi

    Les DP bridge, Facade et consors, cela ne te dit rien

    Et, dans le pire des cas, on peut parfaitement envisager la généricité avec la spécialisation partielle ou totale (pourquoi pas avec un brin de type erasure )

    Mais une chose est sure : jamais, au grand jamais nous n'utiliserons des void *
    Je suis un développeur C++ contrarié et je suis preneur d'un point de vue honnête, complet, sérieux sur ce langage qui me semble bien mieux que Java mais dont hélàs les opportunités sont plus réduites et que mon parcours professionnel témoigne énormément en ce sens (un peu plus d'un an en Cobol et environ 3 en Java).
    Ce qu'il faut comprendre, c'est qu'aucun langage n'est foncièrement mauvais ni foncièrement bon!!!

    On peut éventuellement dire qu'un langage sera plus adapté à un secteur qu'à un autre, mais il faut vraiment voir les besoins pour parler de la sorte

    Et malgré tout le mal que j'ai pu dire de java sur mes dernières interventions, je peux te rassurer : je ne le trouve pas forcément pire qu'un autre (ni forcément meilleur d'ailleurs )

    Cependant, je me demande quelle est la proportion de projets (quel que soit le langage envisagé ) pour lesquels le choix du langage est basé uniquement sur "ce que connait l'initiateur du projet", sur "l'effet de mode" ou sur le fait que c'est, définitivement, le langage le plus adapté aux besoins que l'on doit rencontrer (ou peut etre sur "la tchatche du commercial qui vend le projet ) ...

    Je reste cependant convaincu que le choix d'un langage "de prédilection" reste une affaire de gout et de philosophie personnelle, mais qu'il est malgré tout quasiment indispensable de s'intéresser au moins un tout petit peu aux langages que l'on "apprécie moins", ne serait-ce que pour pouvoir se "dépatouiller avec" en cas de besoin
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #1805
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    octobre 2004
    Messages
    11 511
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : octobre 2004
    Messages : 11 511
    Points : 29 908
    Points
    29 908
    Par défaut
    Citation Envoyé par hegros Voir le message
    Quand au support de la PpC là encore en C# il y a code contract qui permet de faire de la vérification statique et dynamique de code à contrario du C++ ou Java qui de ce que je sais permet de vérifier des contrats surtout de manière dynamique soit à l’exécution (quoique en C++ j'ai un doute avec toute cette méta programmation générique...)
    La dernière mouture de la norme (c++11, en cours d'intégration dans les compilateurs ) introduit les static_assert qui permettent une sortie sur erreur à la compilation (avec un message d'erreur un peu plus compréhensible que les 350 lignes d'erreur propres à son système de gestion des template )

    D'un autre coté, les assert et les exceptions existent toujours au runtime
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #1806
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : août 2005
    Messages : 2 894
    Points : 7 197
    Points
    7 197
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Je n'ai pas vraiment de connaissance en développement d'un compilateur, mais je ne vois pas en quoi ce serait impossible en Java...
    Oublies j'ai dit de la merde
    Je pensais à un interpréteur et non un compilateur ...
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  7. #1807
    Membre confirmé
    Profil pro
    Inscrit en
    avril 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : avril 2006
    Messages : 432
    Points : 578
    Points
    578
    Par défaut
    Citation Envoyé par Nemek Voir le message
    Oublies j'ai dit de la merde
    Je pensais à un interpréteur et non un compilateur ...
    On peut faire une jvm en java compilé (en code natif) ^^

  8. #1808
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    décembre 2005
    Messages
    10 321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : décembre 2005
    Messages : 10 321
    Points : 18 477
    Points
    18 477
    Par défaut
    Citation Envoyé par Ubiquité Voir le message
    On peut faire une jvm en java compilé (en code natif) ^^
    à condition de restreindre certaines fonctionnalités du langage... ou de tricher en compilant un système pour les interpréter
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  9. #1809
    Membre confirmé
    Profil pro
    Inscrit en
    avril 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : avril 2006
    Messages : 432
    Points : 578
    Points
    578
    Par défaut
    Citation Envoyé par gorgonite Voir le message
    à condition de restreindre certaines fonctionnalités du langage... ou de tricher en compilant un système pour les interpréter
    Lesquelles ?
    Pourquoi ?

  10. #1810
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    août 2003
    Messages
    5 273
    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 273
    Points : 10 827
    Points
    10 827
    Par défaut
    Citation Envoyé par Nemek Voir le message
    a- Concernant ces bibliothèques, elles sont codées avec des instructions préprocesseurs ou elles utilisent des .h génériques couplés à des .cpp spécifiques ou autre ? Parce que dans ce cas, soit tu considères que tu as déportés le problème, soit tu considères que tu utilises une VM ...

    b- Ensuite en Java on est très adepte des librairies tierces, et ne pas avoir à les recompiler à chaque fois est une chose non négligeable.

    c- En Java j'ai rarement ressenti un tel besoin qui d'ailleurs tend faire à confondre héritage et composition. Mais j'avoue en avoir parfois ressenti le besoin.[...]
    D'ailleurs, il serait intéressant de voir comment les autres langages qui ont fait le même choix s'en sortent.


    d- Merci pour ce petit cours J'aurais bien aimé que mes profs me présentent les choses de cette manière ; ils n'ont jamais évoqué le Liskov.

    Si je résume bien, cela dit qu'un contrat fixé par un type est valable pour tous les sous-types ? Dommage et heureusement que la programmation par contrat (pré-condition/post-condition) n'existe pas vraiment en Java ... Ca m'arrive de contourer ce principe Mais c'est peut-etre à cause de code mal fichu à la base ...


    e- Tu as un concet de fonction trigo, non ? Donc d'un point de vue OO, un type "Fonction trigonométrique".

    f- Et les "templates" ne sont pas la panacée car chaque "type" regénère du binaire supplémentaire. Et une question, deux "type" d'un même template avec les mêmes paramètres génériques sont-ils substituables ? En gros est-ce que deux déclarations de List d'entier sont substituables ? Si oui, est-ce toujours vrai pour une Liste de voiture et une liste de véhicule ?

    g- Concernant la vérification à la compilation elle n'est valable que si tes listes sont bien spécifiques mais dès que tu en veux des génériques ... T'as le même problème.


    h- [concepts...]
    Pourquoi ne pas le faire si c'est nécessaire ?
    Si je prends une classe assez con : les ensembles. Ton idée ca serait de faire une classe SetElement ? Idem pour les clés d'une map avec MapKey ? Dans ce cas, je pense que finalement Java n'a pas tant de wrapper que ça ...


    i- Bah s'ils ont pas de racine commune tu te retrouves ni plus, ni moins qu'avec des void* ! Mais sans comportement commun.
    a- En interne, il y a 150 façons différentes de réaliser ces points de variations (dans le makefile (ou assimilé) au niveau du choix du .cpp compilé, par préprocesseur, ou autre, peu importe).
    C'est en interne des libs tierces. Dans le code métier que nous développons nous, il n'y a rien de tout ça.
    Il y a aujourd'hui extrêmement peu de raisons pour tester la plateforme dans les codes que l'on tape quotidiennement.

    b- les libs tierces on ne les compile qu'une (série de) fois par plateforme ... quand elles ne viennent pas déjà précompilées.
    Où est le soucis ?

    c- Le peu que j'ai vu de ruby, j'ai beaucoup aimé son approche quant à la séparation héritage orienté substituabilité et import de code.
    Après Java supporte l'héritage multiple et virtuel (mais limité aux interfaces). D'où que n'étant pas capable d'étendre aux comportements, il ne permet pas de supporter la programmation par contrat de façon native avec des contournements façon pattern NVI. (il repose à la place sur une phase de précompilation)

    d- koala a détaillé la chose, je n'y reviens pas.
    Si tu cherches "LSP, liste, liste triée, carré, rectangle, etc" sur dvpz tu devrais trouver des discussions poussées sur le sujet du LSP.

    e- Le concept de fonction trigo ne représente rien. sin et cos ne présentent pas le grand intérêt à être interchangeables.
    Pire instancier cos pour faire le calcul ? Mais voilà un bien étrange idée. Je vois bien le
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Cos cos = new Cos();
    double l = cos.compute(pi) * 42;
    Franchement ? Non.

    f- Oui et non. Dans bien des cas, cela va couter autant de binaire que si on avait fait la même chose à la main (typiquement avec chaines et vecteurs qui sont des surcouches très light au dessus des tableaux C).
    Dans d'autres cas plus complexes (tables), effectivement on peut avoir du code bloating. Il existe des techniques pour l'éliminer quand problématique. Et comme le disait Koala, list<T> et list<T> sont exactement la même chose. Encore heureux.

    g- mais mes listes sont toujours spécifiques.
    Tu ne me verras jamais avoir des listes de carottes et voitures. (même si std::list<boost::any> me le permettrait)
    Et pour les légumes, j'ai des std::list<legumes*> (/boost::ptr_list<legume>/std::list<std::unique_ptr<legume>>/...).
    Et si j'ai besoin de faire des recherches ben ... je n'ai aucun downcasting à réaliser depuis le type Object car le légume exposera le critère sur lequel je réalise ma recherche.
    Si on oublie l'héritage du C relativement aux types primitifs et void*, le typage du C++ induit par les templates est supérieur à celui du Java (pre Generics) -- fichu C!

    h- Parce que ce n'est pas trivial et qu'il y avait eu des soucis à mélanger tous les ajouts du langages concepts, lambda, etc.
    Du coup cela a été botté en touche pour l'instant, pour y revenir éventuellement plus tard.
    Depuis de nouvelles approches sur le sujet ont été évoquées (cf p.ex. le static_if présenté par Alexandrescu au Going Native 2012)

    i- Certainement pas. Je me retrouve avec des templates et un typage très précis sans la moindre racine mémorielle commune (void*).
    Regarde le C (et peut-être même java). Il n'y a pas besoin de void* pour ajouter un int à un double. Ben les templates, c'est pareil.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  11. #1811
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    décembre 2005
    Messages
    10 321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : décembre 2005
    Messages : 10 321
    Points : 18 477
    Points
    18 477
    Par défaut
    Citation Envoyé par Ubiquité Voir le message
    Lesquelles ?
    Pourquoi ?
    tout ce qui est un peu trop dynamique/reflexif/introspectif...

    c'est le même principe que l'introduction du DLR dans .Net ; de RPython pour compiler PyPy, etc.
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  12. #1812
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : août 2005
    Messages : 2 894
    Points : 7 197
    Points
    7 197
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Le fait est que, lorsque tu pars sur le principe d'une super classe de base, tu te retrouveras, fatalement, avec un héritage en diamant!!!
    Pas si tu interdis l'héritage multiple.

    Citation Envoyé par koala01 Voir le message
    L'héritage multiple n'est pas plus mauvais que l'héritage simple: il faut juste se rappeler que l'héritage multiple doit nous inciter à plus de prudence lorsqu'on l'envisage (mais il faut déjà être particulièrement prudent lorsque l'on envisage l'héritage simple, de manière générale )
    Je ne dis pas plus qu'il est mauvais mais ne pas l'avoir allège vachement les choses (d'un point de vue du langage et non du développeur). Par exemple, la recherche d'une implémentation se fait en ligne droite jusqu'à la racine. Et qu'en plus il existe des contournements.

    Citation Envoyé par koala01 Voir le message
    Je ne dis pas qu'il faut penser comme une machine pour programmer, je dis juste qu'il faut connaitre un minimum les principes qui permettent de le faire
    Je parlais surtout des pointeurs dont il faut faire particulièrement attention. Alors peut-être qu'avec le temps ca devient ultra intuitif en ayant des patterns simples et efficaces ; en attendant on doit focaliser une part d'attention à ça, ce qui nous prive de nous focaliser sur autre chose. C'est bien ça qu'offre des plateformes comme Java et .Net
    Et quand je vois le nombre d'applications qui se terminent en Core Dump, je me dis que tout le monde ne les manipules pas si bien que ça.
    Cependant il n'est pas rare des applications Java qui ont de graves fuites mémoires (surtout en environnement modulaire).

    Citation Envoyé par koala01 Voir le message
    Tout comme tu n'oserais sans doute pas laisser coder quelqu'un qui ignore comment choisir entre les différents types de boucles dans n'importe quel langage impératifs, j'estime qu'il ne faut pas s'étonner d'avoir des problèmes lorsqu'on laisse coder les gens avec un langage OO alors qu'il ne comprennent pas (ou pire à moitié) les principes qui régissent le paradigme OO.
    Il y a une marge entre ne pas maîtiser une simple itération et la manipulation mémoire à travers le "cycle de vie" de l'exécution d'un programme ...

    Citation Envoyé par koala01 Voir le message
    Evidemment, il existe, j'en suis convaincu, des gens qui comprennent et maitrisent les principes du paradigme OO et qui codent en java

    Je ne dis que cela!!!
    On est entièrement d'accord. Mais je voulais revenir sur "faire croire à certains qu'ils sont parfaitement compétants". Ca sous-entend que développer en Java ne nécessite pas de compétences. Je reformulerai plutôt en disant qu'elle ne nécessite pas de compétence "bas-niveau" (comprendre penser comme une machine).

    Citation Envoyé par koala01 Voir le message
    Le problème, et je reviendrai là dessus juste un peu plus tard, c'est que java (ou tout langage qui limite volontairement les possibilités du paradigme OO) permet d'obtenir quelque chose "qui marche" en n'ayant qu'une connaissance et une compréhension partielle des principes OO, voire, qui confondent carrément certains principes
    Le langage n'étant pas full-OO, on ne peut pas demander aux développeurs de ce type de langage de l'être. Et puis la théorie c'est bien mais dans les faits il faut que ça marche.

    Citation Envoyé par koala01 Voir le message
    C++ est peut etre, à l'inverse, un peu trop permissif, mais c'est sans doute un bien car la première chose que l'on martèle aux gens, c'est, justement, les principes de base (et pas seulement du paradigme OO ) , et son s'assure qu'il les auront bien compris.
    La permissivité (ou le laisser-aller/faire) ne sont pas, par expérience, didactique. Au contraire, plus tu laisses de liberté aux gens et plus ils en prennent plus que d'être ultra-rigoureux.

    Citation Envoyé par koala01 Voir le message
    Au final, un type qui passe de C++ à java va sans doute pester énormément sur les restrictions qui lui sont imposées, mais il arrivera "facilement" à obtenir une conception qui "tient la route", simplement parce qu'il pourra (pour ne pas dire qu'il devra) se permettre d'appliquer les principes de base avec un peu plus de souplesse.

    A l'inverse, quelqu'un qui passe de java à C++ risque d'avoir énormément de problème parce que, justement, il risque de ne pas avoir la réelle compréhension de ces principes, et donc, de faire des choses qui les violent, bien qu'étant permises par le langage!!!
    C'est bien ce que je disais ^^ Mais la même chose s'applique si tu passes de n'importe quoi (y compris rien) à C++.
    Pour avoir travailler en trinôme à la fac avec des développeurs C++, il n'est pas si simple de passer de celui-ci à Java. Car derrière son apparente facilité Java cache bien quelques subtilités et c'est d'ailleurs comme ça qu'on se retrouve avec des gens qui râlent parce que leurs applications consomment trop de mémoire et/ou trop de CPU ; sans compter les fuites mémoires à répétition.
    De mémoire la chose qui m'a le plus surpris c'est une difficulté à assimilé l'équivalent du passage par référence ; alors qu'ils n'ont aucun problème à traiter les pointeurs.

    Citation Envoyé par koala01 Voir le message
    Mais ce n'est pas le langage qui est mauvais, à ce moment là, c'est le concepteur
    Malheureusement, je pense que c'est souvent à cause du formateur ... Voir mes remarques plus haut concernant l'enseignement que j'ai reçue que ce soit en C++ ou COO (je ne parle pas de POO vu que c'était grandement réduit à Java, un seul petit projet de "médiathèque" en C++).


    Citation Envoyé par koala01 Voir le message
    Le principe de base de l'OO, c'est la substituabilité, au sens du Principe de substitution de Liskov.

    Le principe de l'OO, c'est le fait de pouvoir passer un objet dont le type est Derivee là où j'attends un objet dont le type est Base et que cela continue à fonctionner!!!

    Le polymorphisme découle directement du respect de LSP, mais c'est le fait que, si un comportement est (correctement ) redéfini (et je n'ai pas dit surchargée ) dans la classe Derivee, ce sera le comportement du type Derivee qui sera utilisé et non le comportement de la classe de base (pour autant, bien sur, que nous soyons dans une situation dans laquelle la substitution ait été appliquée )

    Quelque part, ta remarque est la preuve flagrante de ce que j'exprimais quelques lignes plus haut
    Si la différence se limite à la redéfinition, il y a bien un élément essentiel de la COO (d'autant plus que le polymorphisme inclut le Principe de substitution de Liskov).
    Cependant je dois avouer être un peu trop habitué à Java et ces méthodes toutes virtuels. Est-ce que la non-virtualité fait réellement partie de la C00 ? Je ne connais pas beaucoup de langage mais il me semble qu'en Eiffel et Smalltalk (les langages phares de la P00) cela n'existe pas !?
    Enfin en ayant finalement compris la définition de la "substitution", je doute que ce principe soit mal assimilé par les "apprentis" POO-iste. Sinon c'est que je connais que des génies ^^ (Pour information je travaille avec pas mal de personnes issues de cursus autre que le développement : chimie, science des matières, biologie, etc.)

    Citation Envoyé par koala01 Voir le message
    Sur les cinq piliers du paradigme OO (ségrégation de l'interface, inversion des dépendances, responsabilité unique, open / close et principe de substitution de liskov), java vous incite à devenir champion dans trois de ces aspects (ségrégation de l'interface, open / close et inversion des dépendance), mais vous incite à ignorer totalement les deux derniers: "Responsabilité unique ben quoi, ma voiture, elle doit se tracer " "Liskov c'est qui celle là Qu'est ce qu'elle nous a encore pondu comme anerie " sont, à peu de choses près des remarques que j'ai déjà reçues de la part de javaistes (et de quelques codeurs vraiment débutants en C++ quand meme )
    N'ayant que Wikipedia comme source potentiellement fiable (je sais on se refait pas), je t'invite à m'en fournir d'autres... En tout cas ce sont pas "exactement" les principes de bases qui sont évoqués ([URL=http://en.wikipedia.org/wiki/Object-oriented_programming#Fundamental_features_and_concepts]source), il s'agit bien du polymorphisme (de type, merci gl pour la précision ) et non du Principe de Liskov qui est mis en avant ...
    D'ailleurs ces piliers ne seraient pas plutôt des pattern/bonnes pratiques que des fondements ?

    Citation Envoyé par koala01 Voir le message
    C'est une hérésie au sens du respect du LSP, dés le départ!!!
    En fait pas vraiment. Ou en tout cas, je le vois pas. Mais donne moi un exemple concret

    Citation Envoyé par koala01 Voir le message
    CLe simple fait que tu puisses décider de passer "tout et n'importe quoi", sans distinction aucune, y compris (j'ai envide de dire "et surtout") des objets dont les types n'ont, a priori, aucun lien et aucune raison d'avoir le moindre lien, ca ne te choque pas
    Le fait que tu puisses décider de créer une collection (quelle qu'elle soit ) d'objet tout à fait hétéroclites n'ayant aucuns lien entre autre et aucune raison d'en avoir, ca ne te choque pas
    Non ca me choque pas car
    1. ce n'est pas à nous de déterminer si une infinité d'objet dans une infinité de contexte ont un lien ou pas.
    2. si je veux les mettre dans un même panier c'est que je considère qu'il existe un lien
    3. dans le cas de Java et des collections, ca rend le code générique, compatible avec toutes les classes et légèrement optimisé



    Citation Envoyé par koala01 Voir le message
    Plus haut, on m'as dit "oui, c'est pour cela que l'on déconseille fortement de créer une telle collection" (ce n'est pas une citation, mais l'idée est là, hein? ), mais, si vous vous rendez déjà compte que "c'est pas bien" de le faire, comment pourriez vous justifier le fait que le langage vous l'autorise de facto et vous oblige littéralement à faire en sorte que ce soit possible
    Autoriser une chose ou une autre est de facto, une affaire de pragmatisme.
    Il nous oblige en rien ..... directement. Cependant je t'accorde que l'implémentation des générics en Java est vraiment à chier. Tout cela est dûe à un principe de Java de rester rétrocompatible (dans la théorie) ce qui tout aussi à chier. C'est même la grosse épine de Java qui ralentit son évolution et tue parfois dans l'oeuf l'arrivée de nouveau concept/instruction, etc. D'autant plus que cela fait croire à certains qu'on peut changer de version de Java sans impact.

    Citation Envoyé par koala01 Voir le message
    L'héritage en diamant n'est qu'un "cas particulier" de l'héritage multiple
    Il faut donc d'autant plus le traiter dans le langage/compilation/exécution !!!

    Citation Envoyé par koala01 Voir le message
    Évidemment, si on part d'office avec une super classe de base, cela devient le cas général et unique, mais, dans une conception bien faite (allez, je le dis : "dans le monde des bisounours ), les différents comportements obtenus par héritage multiples seront, en réalité, totalement transversaux
    J'admet volontiers qu'il n'y a pas de nécessité d'avoir une base unique. Je dis en revanche que cela a ses avantages. Cela sert la cause de Java et non le contraire. Quiconque manipule un peu l'API se rend compte qu'Object n'est pas dénué de sens et de fonctionnalité contrairement à void.
    N'oublie pas non plus que Object possède une méthode getClass() (qui remettra sûrement cause beaucoup de piliers de OO) qui permet d'en savoir beaucoup sur une instance donnée.

    Citation Envoyé par koala01 Voir le message
    Montre moi un seul bouquin de conception OO qui ne soit pas orienté java ou C# (car ils ont clairement fait le choix de l'obliger ) dans lequel on dit que toute fonction doit d'office faire partie d'un objet, et je pourrai te croire

    Attention, je respecte le choix de java de dire que toute fonction doit etre fonction membre, mais ce n'est nullement une obligation en terme OO
    Je n'ai pas dit cela J'ai dit que l'impératif n'est pas un paradigme intrinsèque à OO.

    Citation Envoyé par koala01 Voir le message
    Celui à qui je faisais allusion a clairement dit qu'il ne voulait pas entendre parler de ce paradigme...

    Mais je ne relèverai pas l'attaque plus ou moins personnelle
    Je suis peut-être un peu bisounours aussi dans l'âme mais je pense que quelqu'un de son "niveau" doit être apte à comprendre OO, d'autant plus s'il se permet d'y porter un jugement de valeur. Bon après je connais pas du tout le type ; je veux pas dire personnellement mais dans l'ensemble (l'image qu'il dégage, etc). C'est peut-être un petit con : tu me confirmeras ou pas !

    Citation Envoyé par koala01 Voir le message
    Que tout puisse être clé de map, à la limite, cela ne me dérange pas...

    Mais que dans une même map, il devienne possible d'avoir un ensemble hétérogène de clés, ca, ca m'inquiète quand meme énormément (oui Luc, tu as bien compris ce que je voulais dire )
    J'ai donné des exemples simples, et je peux, si tu le souhaites, te donner des exemples bien plus concrets
    Bah dans une "Reference Map", je vois aucune obligation d'avoir des clés homogènes ... Après pour te rassurer, on peut faire une sur-map dont les clés sont des types, comme ça toutes les sous-map ont des clés homogènes mais dans la mesure où il n'y a pas de "conflit", je verrais pas d'intérêt à cela.

    Citation Envoyé par koala01 Voir le message
    Maintenant, donne moi un exemple qui tienne la route, qui respecte les principes OO qui me montre que j'ai tort, et je te ferai mes plus plattes excuses
    Pour avoir des excuses, il faudrait avoir été agressé

    Citation Envoyé par koala01 Voir le message
    En les castant en void* oui, mais ca, c'est l'héritage du C (contre lequel on lutte à longueur de journée
    Pour information (et désolé du sacrilège de la syntaxe) mais est-ce que le code suivant compile ?
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Foo* foo = ...;
    Bar* bar = ...;
    if (foo == bar) {
      ...
    }

    Citation Envoyé par koala01 Voir le message
    Que penses tu... du paradigme générique, et des classes (et fonction template)
    Les templates, pwaaa. Et toutes façons ils vont supposer (comme les langages dynamiques) que les membres utilisés existent. Si je prends le cas des HashMap, ton code va supposer que les types qui vont "instancier le template" (?) dispose bien des méthodes de calculs du hash et de comparaison sans qu'ils aient de point commun. Tu ne fais que déclarer des interfaces implicites.

    Concernant le paradigme générique (s'il s'agit bien de la même chose qu'en Java), il faut bien un point commun. D'ailleurs c'est la raison de la présence de Boost::Any non ?

    Citation Envoyé par koala01 Voir le message
    La différence

    C'est que tu restes libre d'utiliser l'un alors que tu es obligé d'utiliser l'autre, même si cela ne t'intéresse pas
    Disons qu'Object en Java est le strict pendant de l'ensemble vide en théorie des ensembles. C'est une base qui représente tout et rien. Donc l'obligation de l'avoir n'apporte pas vraiment de contrainte. Est-ce que le fait de ne pas avoir deux hiérarchies distinctes d'objet est une contrainte ? Je me pose la question ...

    Citation Envoyé par koala01 Voir le message
    C'est étrange, je n'ai jamais utilisé un seul void* dans un code C++... serais-je un extra terrestre
    Peut-être ?
    Ensuite on peut admettre le "workaround" de Luc à savoir autant de type que de comportement générique (ie MapKey, SetEntry, etc.)
    Par curiosité, comment sont codées les hash map en C++ ?

    Citation Envoyé par koala01 Voir le message
    Qui te dis que deux frameworks différents utiliseront fatalement un God Object
    Bah si tu veux les mettre dans une même collection ou les manipuler de manière "homogène".
    Ensuite on peut admettre le "workaround" de Luc à savoir autant de type que de comportement générique (ie MapKey, SetEntry, etc.) (ouais je sais je C//C mais c'est mon pêché mignon).

    Citation Envoyé par koala01 Voir le message
    Où est le pragmatisme quand on n'a pas le choix
    Conceptuellement c'est une aberration mais techniquement cela ne pose aucun problème. Que tu colles ta fonction/procédure dans un namespace Foo::Bar ou une méthode dans une classe foo.Bar, je vois pas la différence

    Citation Envoyé par koala01 Voir le message
    ne t'en fais pas, je n'ai pas l'habitude de prendre la mouche
    Je voulais juste amorcer une réponse intelligente et non sur la défensive
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  13. #1813
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : août 2005
    Messages : 2 894
    Points : 7 197
    Points
    7 197
    Par défaut
    Citation Envoyé par gl Voir le message
    Et tu n'implémentes jamais plusieurs interfaces ?
    Citation Envoyé par gl Voir le message
    • Des interfaces plus riches permettant d'implémenter le NVI (il est possible d'avoir des méthodes finales non abstraites dans ces interfaces).
    Il y a une grosse différence entre l'héritage d'une classe et l'implémentation d'une interface : le code à exécuter est forcément dans la hiérarchie d'héritage.
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  14. #1814
    Membre confirmé
    Profil pro
    Inscrit en
    avril 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : avril 2006
    Messages : 432
    Points : 578
    Points
    578
    Par défaut
    Citation Envoyé par gorgonite Voir le message
    tout ce qui est un peu trop dynamique/reflexif/introspectif...

    c'est le même principe que l'introduction du DLR dans .Net ; de RPython pour compiler PyPy, etc.
    Un langage "dynamique" peut bien être compilé !? Lisp l'est bien par exemple.

  15. #1815
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    décembre 2005
    Messages
    10 321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : décembre 2005
    Messages : 10 321
    Points : 18 477
    Points
    18 477
    Par défaut
    Citation Envoyé par Ubiquité Voir le message
    Un langage "dynamique" peut bien être compilé !? Lisp l'est bien par exemple.

    tu parles de Bigloo ou Stalin ?

    en fait, j'ai surtout vu que le programme était surtout transformé sous la forme d'une énorme continuation, qui était ensuite simplifiée autant que possible, et le reste

    enfin, on sort du cadre de la discussion... il faudrait faire un vrai sujet et prendre le temps de bien définir chaque notion et expliquer les phases de compilation et les "astuces/arnarques" pour pallier aux manques. (ce qu'on a déjà fait partiellement dans une vingtaine de discussions... si quelqu'un a le courage de faire une synthèse )
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  16. #1816
    Membre confirmé
    Profil pro
    Inscrit en
    avril 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : avril 2006
    Messages : 432
    Points : 578
    Points
    578
    Par défaut
    Citation Envoyé par gorgonite Voir le message
    tu parles de Bigloo ou Stalin ?

    en fait, j'ai surtout vu que le programme était surtout transformé sous la forme d'une énorme continuation, qui était ensuite simplifiée autant que possible, et le reste

    enfin, on sort du cadre de la discussion... il faudrait faire un vrai sujet et prendre le temps de bien définir chaque notion et expliquer les phases de compilation et les "astuces/arnarques" pour pallier aux manques. (ce qu'on a déjà fait partiellement dans une vingtaine de discussions... si quelqu'un a le courage de faire une synthèse )
    Je parle de Common Lisp, qui peut être compilé en code natif.

  17. #1817
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    décembre 2005
    Messages
    10 321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : décembre 2005
    Messages : 10 321
    Points : 18 477
    Points
    18 477
    Par défaut
    Citation Envoyé par Ubiquité Voir le message
    Je parle de Common Lisp, qui peut être compilé en code natif.

    je ne suis pas fan de la famille Lisp/Scheme

    alors, de ce que j'ai lu rapidement, il y aurait
    • un mécanisme d'expansion de macro à la "compilation" (ok, assez classique)
    • un mécanisme de compilation classique inclut dans la spécification



    Par contre, code natif ne veut pas forcément dire que l'on ne va pas intégrer un mécanisme d'interprétation dans le code généré

    Citation Envoyé par Wikipedia sur la reflexion
    In a compiled language that supports runtime creation of functions, such as Common Lisp, the runtime environment must include a compiler or an interpreter.
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  18. #1818
    Membre confirmé
    Profil pro
    Inscrit en
    avril 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : avril 2006
    Messages : 432
    Points : 578
    Points
    578
    Par défaut
    Citation Envoyé par gorgonite Voir le message
    je ne suis pas fan de la famille Lisp/Scheme

    alors, de ce que j'ai lu rapidement, il y aurait
    • un mécanisme d'expansion de macro à la "compilation" (ok, assez classique)
    En fait les macro de Lisp n'ont rien de classique.
    Citation Envoyé par gorgonite Voir le message
    • un mécanisme de compilation classique inclut dans la spécification



    Par contre, code natif ne veut pas forcément dire que l'on ne va pas intégrer un mécanisme d'interprétation dans le code généré
    Dans le cas de Lisp, c'est pour interpréter (ou compiler) du code Lisp produit au run-time. Java n'a pas, à ma connaissance, cette capacité.


    Par contre là je suis complètement hors sujet.

  19. #1819
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    décembre 2005
    Messages
    10 321
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : décembre 2005
    Messages : 10 321
    Points : 18 477
    Points
    18 477
    Par défaut
    Citation Envoyé par Ubiquité Voir le message
    En fait les macro de Lisp n'ont rien de classique.
    pas forcément classique au sens "macros C"... mais ça reste classique au sens méta-programmation


    Citation Envoyé par Ubiquité Voir le message
    Dans le cas de Lisp, c'est pour interpréter (ou compiler) du code Lisp produit au run-time. Java n'a pas, à ma connaissance, cette capacité.
    oui et ?
    java n'a jamais été une référence en théorie des langages... mais clairement c'est HS ici
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  20. #1820
    Membre confirmé
    Profil pro
    Inscrit en
    avril 2006
    Messages
    432
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : avril 2006
    Messages : 432
    Points : 578
    Points
    578
    Par défaut
    Citation Envoyé par gorgonite Voir le message
    pas forcément classique au sens "macros C"... mais ça reste classique au sens méta-programmation
    En tout cas il y a très peu de langage qui propose une "feature" comme les macro Lisp.

    Citation Envoyé par gorgonite Voir le message
    oui et ?
    Je répondais à ca :
    Citation Envoyé par gorgonite Voir le message
    à condition de restreindre certaines fonctionnalités du langage... ou de tricher en compilant un système pour les interpréter
    Ce qui force un programme Lisp à intégrer un interpréteur ou un compilateur est une propriété que n'a pas Java.

Discussions similaires

  1. [Débat] Technologie .NET vs JAVA
    Par neo.51 dans le forum Débats sur le développement - Le Best Of
    Réponses: 1047
    Dernier message: 14/01/2019, 17h15
  2. [Débat] .NET vs JAVA/J2EE
    Par tssi555 dans le forum VB.NET
    Réponses: 5
    Dernier message: 10/12/2008, 08h54

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