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

Java Discussion :

Des ingénieurs d’Oracle proposent d’étendre Java avec des types intermédiaires


Sujet :

Java

  1. #1
    Expert éminent sénior

    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Août 2011
    Messages : 283
    Points : 18 071
    Points
    18 071
    Par défaut Des ingénieurs d’Oracle proposent d’étendre Java avec des types intermédiaires
    Des ingénieurs d’Oracle proposent d’étendre Java avec des types intermédiaires
    à mi-chemin entre les classes et les types primitifs

    « Codé comme une classe, fonctionne comme un entier », voilà la devise de trois ingénieurs d’Oracle pour améliorer le langage Java. En effet, Brian Goetz, John Rose et Guy Steele viennent de publier le premier draft de leur proposition qui s’intitule State of the Values .

    Leur proposition qui est encore à ses balbutiements vise à étendre le langage Java et la JVM avec une nouvelle catégorie de type appelée Value types qui devrait s’inscrire à mi-chemin entre les types primitifs et les classes. Le but de la manœuvre est de créer de nouveaux types qui seraient codés comme une classe et qui bénéficieraient des mécanismes qui lui sont spécifiques comme l’encapsulation, tout en offrant de meilleures performances en termes de mémoire utilisée et de CPU que les classes.

    Les trois instigateurs de cette proposition appuient leur idée avec un constat simple : les objets font appel à la notion d’identité de l’objet qui est là en premier lieu pour permettre la mutabilité et le polymorphisme, ce qui a un cout important sur les performances du langage et de la JVM.

    Toutefois, dans certains cas, l’utilisateur code une classe qui s’affranchit de la notion d’identité de l’objet. Par exemple, l’utilisateur définit en premier lieu une classe Point qui représente un point sur un plan 2D, en sachant que cette dernière ne sera pas « castée » en un autre objet. Il devient intéressant de l’avoir comme un Value Types.

    Enfin, il est important de noter que cette proposition peut ouvrir la voie à pas mal d’améliorations pour le langage Java comme le soulignent les trois ingénieurs. Cela permettrait notamment de définir certains nombres mathématiques qui ne sont pas encore présents comme les nombres complexes ou permettre le support de certains types natifs et spécifiques aux processeurs modernes, sans oublier un tas d’autres améliorations telles que notées dans leur proposition.

    Source : State of the Values

    Et vous ?

    Qu’en pensez-vous ?

    Pensez-vous que cette proposition peut être bénéfique au langage ? Pourquoi ?

  2. #2
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 320
    Points : 3 741
    Points
    3 741
    Billets dans le blog
    12
    Par défaut
    C'est peut-être un début pour essayer de rendre Java un langage full object, les variables primitives Java deviendraient peut-être des classes, et peut-être que les Wrapper ne seront plus utilisés (j'ai lu quelques articles dans lequel on parle d'un Java 9 qui casse le backward compatibily...).
    Bien sur coté performance il y aura certainement un impact négatif.

    L'avantage des "value class", c'est qu'on pourra peut-être simplifier l'utilisation des objets mutables (je pense à BigInteger et BigDecimal). Et peut-être ainsi étendre l'utilisation de la technologie Java dans le domaine des banques et assurances, dans lequel le COBOL est encore (et toujours) utilisé.

    La question que je me pose est : devrait-t-on utiliser le mot-clé "new" pour instancier une "value class" ?
    Pour moi c'est un mot clé qui devrait justement être réservé aux "vraies" classes Java, dont les objets passent par copie de référence, et dont les méthodes sont polymorphes. Pourtant dans l'exemple du lien ils le font avec la "value class" Point.
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  3. #3
    Membre émérite
    Avatar de Voyvode
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 476
    Points : 2 678
    Points
    2 678
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    C'est peut-être un début pour essayer de rendre Java un langage full object[…]
    C'est effectivement un des grands objectifs d'Oracle pour les prochaines versions.

    Citation Envoyé par Gugelhupf Voir le message
    Bien sur coté performance il y aura certainement un impact négatif.
    Rendre objet les types primitifs tout en conservant leur performance me semble justement l'intérêt (et le défi) de ce type spécial.

    Citation Envoyé par Gugelhupf Voir le message
    Et peut-être ainsi étendre l'utilisation de la technologie Java dans le domaine des banques et assurances, dans lequel le COBOL est encore (et toujours) utilisé.
    [blague méchante/]COBOL existe encore là-bas parce que ces grippe-sous ne veulent pas payer de véritables développeurs. [/blague méchante]

  4. #4
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 320
    Points : 3 741
    Points
    3 741
    Billets dans le blog
    12
    Par défaut
    Les développeurs COBOL sont des vrais développeurs, mais... d'une autre époque on va dire... Et puis il y a :
    • des milliards de lignes de codes déjà fait en COBOL
    • des employés qui ne savent faire que du COBOL
    • des partenariats avec IBM

    Comment remplacer cela par une autre solution du jour au lendemain ? Ce n'est tout bonnement pas possible. De plus, il me semble que :
    • niveau performance, ça doit surement être presque du même niveau qu'un binaire du C pour la conso CPU & mémoire.
    • certaines banques ont déjà mis en place des outils graphiques pour le développement (proche du diagramme d'activité UML), cela génère ensuite du script COBOL qui sera ensuite compilé et exécuté par le mainframe.



    Pour en revenir au sujet, je sais que ce projet n'est qu'à ses balbutiements mais, au lieu d'avoir deux mots-clés pour créer une "value type" (ou "value class"):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    final __ByValue class Point { ...
    Ils devraient plutôt faire usage du mot-clé "struct". Bien sur sa signification n'aura pas la même chose qu'en C ou C++, un peu comme l'a fait C# pour sa version du struct.

    Je pense qu'une "value type" devrait pouvoir hériter d'une autre "value type", d'après eux ce n'est pas possible car :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Can a concrete value class extend another value type? No. (Because concrete value classes are final.)
    Histoire de mutabilité...

    Puis pour l'instanciation d'une "value type", ne pas utiliser le mot-clé "new" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    decimal salary1; // pas d'argument, constructeur par défaut
    decimal salary2(); // ou bien
    decimal salary3(100, 2);
    Un peu comme en C++, sans le risque de confusion avec la déclaration de prototype de fonction.
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  5. #5
    Membre chevronné
    Avatar de la.lune
    Homme Profil pro
    Directeur Technique
    Inscrit en
    Décembre 2010
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Comores

    Informations professionnelles :
    Activité : Directeur Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2010
    Messages : 545
    Points : 2 084
    Points
    2 084
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    C'est peut-être un début pour essayer de rendre Java un langage full object, les variables primitives Java deviendraient peut-être des classes, et peut-être que les Wrapper ne seront plus utilisés (j'ai lu quelques articles dans lequel on parle d'un Java 9 qui casse le backward compatibily...).
    Bien sur coté performance il y aura certainement un impact négatif.
    Pour ce qui est le fait de la mort des types primitifs c'est déjà tranché pour Java 10 et non 9, mais ça ne veut pas dire qu'on aura à faire des new pour déclarer des objets. Mais ce qui est sûr ce qui veulent entamer une chose pareil voient le vrai gain, mais pas pour faire juste pour faire beau.

    Personnellement je ne vois pas d'impacte négatif au contraire je vois une très bonne chose car ça éviterait des casting insensé et permettre la généricité sur des "type primitif" comme vous savez qu'en Java on peut pas faire List<int> , du coup on fera forcement List<Interer> et des casting implicite ou explicites se passent, ou appel de méthodes pour manipuler les valeurs.

    Surtout actuellement avec l'API Stream qu'on tend à éliminer les boucles d'itération sur les tableaux au profit de la programmation fonctionnelle et parallèle il faudra forcement une vraie innovation sur les types primitifs, car la manipulation des types primitifs avec Stream passent par les Wrappers, alors Java 10 permettra des gain en performance.

    Citation Envoyé par Gugelhupf Voir le message
    C'est peut-être un début pour essayer de rendre Java un langage full object
    Les Value types si on comprend bien le challenge ils n'ont rien n'avoir avec le fait de transformer les types primitifs en en Objet. Au contraire ça va dans le sens contraire, on veut réduire et simplifier la manière d'utilisation de certains objets comme des valeurs primitifs et bien les organiser au niveau de la mémoire encore des gain.

    J'avais pensé à côté de la plaque pour les exemples que j'avais donné

  6. #6
    Membre régulier
    Homme Profil pro
    Inscrit en
    Juin 2012
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2012
    Messages : 29
    Points : 110
    Points
    110
    Par défaut
    A vue de nez, ça me fait un peu penser à ce qui se fait en Scala (sauf qu'Oracle pourrait pousser à implémenter des optimisations pour ce genre de chose directement dans la JVM). En Scala, la hiérarchie des types différencie aussi les "value types", qui héritent du type AnyVal (ce sont, en particulier, tous les types qui peuvent être représentés par des types primitifs dans la JVM), et les classes qui héritent de ValueRef (un alias de java.lang.Object).

    Mais AnyVal et AnyRef héritent tous deux du type Any, qui définie les méthodes comme toString, equals ou hashcode - donc les "value types" se comportent comme n'importe quels objets au niveau du code source, sans qu'on ait besoin de savoir si, dans le bytecode, ils seront représentés par des types primitifs (chaque fois que c'est possible) ou wrappés dans des objets (quand c'est nécessaire) - c'est le boulot du compilateur.

    Du coup, on peut écrire (en indiquant explicitement les types, même si ce n'est pas obligatoire) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    val i: Int = 1 + 1 // "i" et "1" seront des types primitifs dans le bytecode : pas de perte de performance ici
    val j: Boolean = i.equals(2) // On peut manipuler i comme n'importe quel objet si besoin, donc appeler une de ses méthodes
    val k: BigInt = BigInt(1) + BigInt(1) // En fait, l'opérateur "+" à la première ligne était aussi lisible comme un appel
                                          // de méthode sur un objet, même si ça ne sera pas le cas dans le bytecode
    Citation Envoyé par Gugelhupf Voir le message
    L'avantage des "value class", c'est qu'on pourra peut-être simplifier l'utilisation des objets mutables (je pense à BigInteger et BigDecimal). Et peut-être ainsi étendre l'utilisation de la technologie Java dans le domaine des banques et assurances, dans lequel le COBOL est encore (et toujours) utilisé.
    Je pense que tu voulais dire "des objets immutables".

    Sinon, la différence de comportement entre objets et types primitifs est effectivement assez énervante en Java (comparé à des langages comme Scala ou C#) - devoir utiliser l'opérateur "+" pour un int mais la méthode "add" pour un BigInt, sous prétexte que leur implémentation est différente, n'a pas vraiment de sens... Mais il y a d'autres possibilités intéressantes indiquées dans le lien, comme les tuples ou les types Optional ou Choice (tiens, là aussi des choses qui existent en Scala ).

    Pour remplacer le COBOL, par contre, oublie - de toutes façons, le problème n'est pas de savoir quel langage est le plus adapté, mais de savoir qu'il y a une montagne de code COBOL qui fonctionne déjà dans toutes les banques.

  7. #7
    Membre chevronné
    Avatar de la.lune
    Homme Profil pro
    Directeur Technique
    Inscrit en
    Décembre 2010
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Comores

    Informations professionnelles :
    Activité : Directeur Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2010
    Messages : 545
    Points : 2 084
    Points
    2 084
    Par défaut
    Citation Envoyé par Cyäegha Voir le message
    Sinon, la différence de comportement entre objets et types primitifs est effectivement assez énervante en Java (comparé à des langages comme Scala ou C#) - devoir utiliser l'opérateur "+" pour un int mais la méthode "add" pour un BigInt, sous prétexte que leur implémentation est différente, n'a pas vraiment de sens... Mais il y a d'autres possibilités intéressantes indiquées dans le lien, comme les tuples ou les types Optional ou Choice (tiens, là aussi des choses qui existent en Scala ).
    Mais je voulais demandé ce que tu reproche réellement aux primitifs en Java, d'abord int peut se comporter comme un Integer qui est normalement un objet et l'autre un type primitif ce qui fait qu'on peut faire:
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
      int a=new Integer(3)+new Integer(6); 
        long r=new Long(200_000_0000)+3L;
         Integer i=23+2;
         boolean b=i.equals(25);//true
         int g=0b0101_1110_10101;//3029
         Integer m=g+10;//3029
         int z=12_000 +new Integer("2334");
    Mais pour ce qui est des types comme BigInteger il faut comprendre que pour manipuler des littéraux qui représentent des nombres au delà de la capacité des types primitifs existants ça ne va même pas compiler, le plus grand entier c'est un long, qui est le Long.MAX_VALUE==9223372036854775807L alors écrire un nombre dépassant cela ne va même pas compiler je ne peux pas écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     long l=2334714582546254672783472523565263528736753752635287367537L;
    car cela n'est pas une valeur primitive valie. Mais je peux écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     BigInteger b=new BigInteger("2334714582546254672783472523565263528736753752635287367537");
    BigInteger bb = new BigInteger(new byte[]{2,3,3,4,7,1,4,5,8,2,5,4,6,2,5,4,6,7,2,7,8,3,4,7,2,5,2,3,5,6,5,2,6,3,5,2,8,7,3,6,7,5,3,7});
    b.add(bb)
    Ici les calculs passent pas décomposition des nombres car le processeur est incapable de faire un calcul sur ces nombres directement, c'est un problème des systèmes dans tous les langages de programmation on s'expose au même problème, ça n'a rien n'avoir avec Java. Ainsi, il n'existe pas un constructeur BigInteger(int) pas de possibilité de faire new BigInteger(123) car ça n'a pas de sens de faire appel à un constructeur de BigInteger si c'est pour manipuler un int ou un long, la limite c'est la limite que supporte un long.

    Alors à quoi ça sert vraiment de faire pour des BigInteger: b+b1 alors que ça serait forcement un surcharge d’opérateur vu que il n y a pas vraiment de calcul sur des BigInteger et BigDecimal, moi je me demande comment en Scala on va pouvoir insérer un grand nombre dans un BigInt alors que ni la JVM ni .Net que Scala est compilé vont pouvoir faire un calcul pareil, impossible, à moins que le compilateur va compiler b+b1 en b.add(b1) vu qu'ils sont tous les deux des BigInt

  8. #8
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par Arsene Newman Voir le message
    [B]Par exemple, l’utilisateur définit en premier lieu une classe Point qui représente un point sur un plan 2D, en sachant que cette dernière ne sera pas « castée » en un autre objet.
    Dommage le choix de l'exemple

    Point, Point2D.Float, Point2D.Double, tous étendent Point2D et le typecasting arrive entre Point2D et Point2D.Double, parfois

  9. #9
    Membre chevronné
    Avatar de la.lune
    Homme Profil pro
    Directeur Technique
    Inscrit en
    Décembre 2010
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Comores

    Informations professionnelles :
    Activité : Directeur Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2010
    Messages : 545
    Points : 2 084
    Points
    2 084
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Dommage le choix de l'exemple

    Point, Point2D.Float, Point2D.Double, tous étendent Point2D et le typecasting arrive entre Point2D et Point2D.Double, parfois
    C'est ça aussi que je trouve intéressant s'ils bossent pour définir des règles de conversion implicites entre les nombres, car rien de m'empêche de faire double a=2; ou int b=2; float c=a;
    Mais le challenge serait sur la manière dont ils vont compiler et manipuler ces nombres au fond de la mémoire car si au préalable j'ai un point Point dont x et y sont des double alors forcement ils vont réserver de l'espace mémoire de deux double même si en fait on va introduire de simples float ou même des byte .

    Par là on voit l’intérêt de Java 10, s'ils offrent une souplesse sur la manipulation de valeur primitifs pas juste transformer les valeur en wrapper, là la valeur sera stocké telle qu'il est, pas question de réserver de l'espace mémoire qui ne sera pas utilisé. Déjà on se demande pourquoi autant de types primitifs dont les développeurs ne savent pas s'en servir vraiment. Rare que tu trouve des code par ici par là on utilise les types short ou byte vaut mieux avoir partout des références sur le tas, avec une inférence de type très fort.

  10. #10
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    je peux pas te dire pour short, mais des que tu lit des fichiers, tu tape dans le byte

    Pour le Point, si il y a plusieurs type différent, c'est justement parce la mathématique entre le double et le int n'est pas la même. Avec des int je peux faire a == b. Avec des doubles, c'est dangereux!

  11. #11
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par Cyäegha Voir le message
    devoir utiliser l'opérateur "+" pour un int mais la méthode "add" pour un BigInt, sous prétexte que leur implémentation est différente, n'a pas vraiment de sens...
    Et justement, ça n'a rien à voir avec les implémentations. C'est une question de définition du langage.

    Il y a en Java, exactement 8 types primitifs. Pas moins, pas plus. 8. Pour certains d'entre eux, ça a un sens de prévoir un opérateur d'addition : double, float, long, int, short, byte et char. Pour d'autres, ça n'a pas de sens : boolean. Donc l'opérateur d'addition a été prévu pour les 7 types primitifs connus pour lesquels il a un sens, et pas pour les autres.

    BigInteger, par contre, est une classe. Une classe comme une autre. Il y a en Java un nombre indéfini de classes, ça change tout le temps. De manière générale, par exemple dans le cas chien + facture, un opérateur d'addition n'a pas de sens entre deux types classe, ou objet de manière générale. Il n'y a donc pas eu tentative d'insérer dans le langage un opérateur qui, par définition, ne peut pas marcher. Les méthodes, en revanche, sont des mécanismes qu'on peut appliquer à tous les types objet, donc si on a un type additionnable, il suffit de lui donner une méthode add().
    Il a été décidé pour le langage Java que la classe BigInteger, n'est pas si intéressante pour mériter d'être un cas particulier de sorte d'avoir un opérateur qui marche qu'avec elle. Même si ça avait été le cas, ça n'aurait pas résolu le besoin de nouvelles classes de nombres additionnables, dont Java ne pourrait pas deviner que ce sont des cas particuliers.
    Certaines classes, en Java, sont spéciales. Les classes wrappers. La classe String. La classe Object, ascendante de tous les types objets. Il y a une méthode qui est un xas particulier, aussi, getClass(). Mais pas BigInteger ni son add().
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  12. #12
    Membre chevronné
    Avatar de la.lune
    Homme Profil pro
    Directeur Technique
    Inscrit en
    Décembre 2010
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Comores

    Informations professionnelles :
    Activité : Directeur Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2010
    Messages : 545
    Points : 2 084
    Points
    2 084
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Pour le Point, si il y a plusieurs type différent, c'est justement parce la mathématique entre le double et le int n'est pas la même. Avec des int je peux faire a == b. Avec des doubles, c'est dangereux
    Je comprend pas le danger côté mathématique, je sais qu'en programmation 3.0 n'est pas 3, mais mathématiquement sont les même. Par définition si x est un nombre réel alors elle est une quantité dont la représentation donne décimal x=n+0.d1d2d3... ou n un nombre entier et d1,d2,d2 des entier compris entre 0 et 9.
    En effet 5.23= 5+0.23, ainsi 3.0 = 3+0.0 or 0.0=0 et 3+0=3, donc 3.0=3. Et selon la regèle de construction des réel R=N U Z U Q U R\Q . Et la relation suivante est toujours vraie N⊂Z⊂Q⊂R car Z={N}U{-N}; Q=Z/Z donc Q={N}U{-N}/{N}U{-N} seulement Q⊄R\Q, mais R\Q⊂R . Déjà en programmation on n'a pas un type qui représente des irrationnels tout court ni des rationnels non incluant les entiers relatifs Q\Z. Une chose est sûr que si je dis que soit n un entier, alors pas possible d'avoir un nombre à virgule dans n, sémantiquement oui, mais je n'arrive pas à saisir le danger de faire a==b entre doubles.

  13. #13
    Membre éclairé
    Homme Profil pro
    web a11y
    Inscrit en
    Avril 2014
    Messages
    153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : web a11y
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2014
    Messages : 153
    Points : 708
    Points
    708
    Par défaut Humeur taquine (c'est vendredi, après tout !)
    Lecteurs du vendredi, bonjour !

    Citation Envoyé par Gugelhupf Voir le message
    C'est peut-être un début pour essayer de rendre Java un langage full object
    est-ce vraiment l'objectif ?

    <mode Troll /ON>
    Tout ce boulot revenir à Smalltalk ?
    <mode Troll /OFF>

  14. #14
    Membre confirmé
    Profil pro
    Expert technique .NET
    Inscrit en
    Août 2007
    Messages
    272
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Expert technique .NET

    Informations forums :
    Inscription : Août 2007
    Messages : 272
    Points : 530
    Points
    530
    Par défaut
    <mode Troll /ON>
    Tout ce boulot revenir à Smalltalk ?
    <mode Troll /OFF>
    <mode Troll /ON>
    Ou comment prouver encore une fois l'obsolescence de JAVA ...
    <mode Troll /OFF>

  15. #15
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par la.lune Voir le message
    mais je n'arrive pas à saisir le danger de faire a==b entre doubles.
    Parce qu'avec un nombre de bits finis on ne peut représenter qu'un ensemble fini de valeurs différentes, or, entre n'importe quels deux réels il existe une infinité de réels compris entre ces deux réels. Conclusion : les réels ne peuvent pas être représentés avec des bits. Dans la mesure où le but des double est de faire comme si on pouvait quand même, cela signifie que les représentations et les calculs seront approchés, pas exacts.

    Et si, en calculs exacts, on s'attend à trouver égalité entre deux nombres calculés, en calculs approchés les mêmes nombres calculés ont de grandes chances de finir différents du fait des approximations.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  16. #16
    Membre chevronné
    Avatar de la.lune
    Homme Profil pro
    Directeur Technique
    Inscrit en
    Décembre 2010
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Comores

    Informations professionnelles :
    Activité : Directeur Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2010
    Messages : 545
    Points : 2 084
    Points
    2 084
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Conclusion : les réels ne peuvent pas être représentés avec des bits. Dans la mesure où le but des double est de faire comme si on pouvait quand même, cela signifie que les représentations et les calculs seront approchés, pas exacts.

    Et si, en calculs exacts, on s'attend à trouver égalité entre deux nombres calculés, en calculs approchés les mêmes nombres calculés ont de grandes chances de finir différents du fait des approximations.
    Mais si c'était ça le problème alors je tiens à dire que même dans le monde réel en mathématiques on ne calcule pas des valeurs exactes si on veut calculer, on se contente d'un valeur approché par excès ou par défaut avec une précision de 10^-n n : la précision. Les vrai valeurs exactes sont soit des entier ou rationnel dont le nombre de chiffre après la virgule est fini mais les valeurs exactes on les cherche pas, on peut juste dire que x=ln(2) dans la théorie mais personne ne saura c'est quoi x exactement.

    Pi est un nombre irrationnel on le connait pas et la calculatrice nous donne une valeur approchée, mais on fait avec car selon la grandeur dont on travail on a pas besoin d'aller à une précision aussi profonde. Seulement dans certaines mesures on calcul et on garde toujours l'erreur delta, ce qui fait qu'après on dit la valeur est égal à tel plus ou moins delta, on utilise des inégalités si on veut savoir que la valeur calculer est dans les bornes. Alors je ne vois pas le fou qui allait calculer des réel et cherche par exemple une limite donnée et comparer après si a==b, ça ne se fait jamais.

    Alors si on connait le contexte qu'on travail et le programme qu'on fait on aura à bien maîtriser ce qu'on fait. Celui qui fait a==b pour des doubles le compilateur ne n=lui dira rien, donc le danger n'est pas sur le programme mais sur celui qui code qui ne sait pas ce qu'il cherche.

  17. #17
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par la.lune Voir le message
    Je comprend pas le danger côté mathématique, je sais qu'en programmation 3.0 n'est pas 3, mais mathématiquement sont les même. Par définition si x est un nombre réel alors elle est une quantité dont la représentation donne décimal x=n+0.d1d2d3... ou n un nombre entier et d1,d2,d2 des entier compris entre 0 et 9.
    Billet ici qui explique pourquoi il ne faut pas utiliser == ou != avec des nombres flottants:

    http://randomascii.wordpress.com/201...-2012-edition/

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public static void main(String[] args) {
     
    		double f = 0.1;
    		double sum;
    		sum = 0;
     
    		for (int i = 0; i < 10; ++i)
    		    sum += f;
    		double product = f * 10;
    		System.out.printf("sum = %1.15f, mul = %1.15f, mul2 = %1.15f\n",
    		        sum, product, f * 10);
    		System.out.println ("sum == product?"+(sum==product));
     
    	}
    Même si mathématiquement le code est correct en considérant que sum==product, informatiquement, c'est faux. Et quand on met == entre deux double, c'est, en général, qu'on assume que deux calculs ont donné le même résultat sur le plan mathématique, pas informatique. Et du coup, ça peut bugger là où on pense que c'est bon.

  18. #18
    Membre régulier
    Homme Profil pro
    Inscrit en
    Juin 2012
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2012
    Messages : 29
    Points : 110
    Points
    110
    Par défaut
    Citation Envoyé par la.lune Voir le message
    Mais je voulais demandé ce que tu reproche réellement aux primitifs en Java, d'abord int peut se comporter comme un Integer qui est normalement un objet et l'autre un type primitif ce qui fait qu'on peut faire:
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
      int a=new Integer(3)+new Integer(6); 
        long r=new Long(200_000_0000)+3L;
         Integer i=23+2;
         boolean b=i.equals(25);//true
         int g=0b0101_1110_10101;//3029
         Integer m=g+10;//3029
         int z=12_000 +new Integer("2334");
    Mon reproche est que Java ait une syntaxe différente entre les types primitifs et les objets, alors que cette distinction est inutile. Dans ton exemple, int ne se comporte pas comme un Integer, il est juste autoboxé dans un Integer - ce n'est jamais qu'une conversion implicite, et cette conversion est bien visible dans le code source, même si tu n'as pas besoin d'écrire Integer.valueOf(a). Ça ne résout pas tout - par exemple, tu ne peux pas déclarer une List<int>, tu ne peux pas appeler toString() sur un int, l'opérateur == n'a pas le même sens pour un type primitif et pour un objet, etc.

    Citation Envoyé par la.lune Voir le message
    Mais pour ce qui est des types comme BigInteger il faut comprendre que pour manipuler des littéraux qui représentent des nombres au delà de la capacité des types primitifs existants ça ne va même pas compiler, le plus grand entier c'est un long, qui est le Long.MAX_VALUE==9223372036854775807L alors écrire un nombre dépassant cela ne va même pas compiler je ne peux pas écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     long l=2334714582546254672783472523565263528736753752635287367537L;
    car cela n'est pas une valeur primitive valie. Mais je peux écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     BigInteger b=new BigInteger("2334714582546254672783472523565263528736753752635287367537");
    BigInteger bb = new BigInteger(new byte[]{2,3,3,4,7,1,4,5,8,2,5,4,6,2,5,4,6,7,2,7,8,3,4,7,2,5,2,3,5,6,5,2,6,3,5,2,8,7,3,6,7,5,3,7});
    b.add(bb)
    Ici les calculs passent pas décomposition des nombres car le processeur est incapable de faire un calcul sur ces nombres directement, c'est un problème des systèmes dans tous les langages de programmation on s'expose au même problème, ça n'a rien n'avoir avec Java. Ainsi, il n'existe pas un constructeur BigInteger(int) pas de possibilité de faire new BigInteger(123) car ça n'a pas de sens de faire appel à un constructeur de BigInteger si c'est pour manipuler un int ou un long, la limite c'est la limite que supporte un long.

    Alors à quoi ça sert vraiment de faire pour des BigInteger: b+b1 alors que ça serait forcement un surcharge d’opérateur vu que il n y a pas vraiment de calcul sur des BigInteger et BigDecimal, moi je me demande comment en Scala on va pouvoir insérer un grand nombre dans un BigInt alors que ni la JVM ni .Net que Scala est compilé vont pouvoir faire un calcul pareil, impossible, à moins que le compilateur va compiler b+b1 en b.add(b1) vu qu'ils sont tous les deux des BigInt
    Quelques remarques :
    - C'est un détail, mais il existe une méthode statique BigInteger.valueOf(long), donc je ne vois pas en quoi c'est très important de ne pas avoir un constructeur BigInteger(int) ? Si on mélange des très grands nombres et d'autres plus petits dans un même calcul, ça n'a rien d'aberrant (surtout qu'il n'y a pas de BigInteger.add(long)... Et pas de conversion implicite, la faute là encore à la différence de traitement entre objets et primitifs).
    - Quasiment tout ce que tu dis concerne des détails d'implémentation. Oui, l'addition sur des entiers de taille arbitraire doit être implémentée différemment (et sera plus lente) - ça n’empêche pas la classe BigInteger de Java d'avoir une méthode add, qui effectue une addition de façon équivalent à l'opérateur "+" sur un entier primitif. La JavaDoc le dit bien : "All operations behave as if BigIntegers were represented in two's-complement notation (like Java's primitive integer types). BigInteger provides analogues to all of Java's primitive integer operators, and all relevant methods from java.lang.Math.". Un BigInteger fournit les même fonctionnalités qu'un long ou un int, mais pour des nombres plus grands (au prix de performances moindre, ce qui parait assez évident).
    - Oui, la surcharge des opérateur est nécessaire pour que ça ait du sens. Ça existe en Scala (de façon élégante mais un peut trop permissive à mon goût - on peut inventer tous les opérateurs qu'on veut) et en C# (pour une liste d'opérateurs prédéfinis, afin d'éviter les opérateurs "exotiques"). Le propositions de "value types" en Java semble aller tout doucement dans ce sens, en proposant que == délègue à la méthode equals, et en posant (sans y répondre) la question du futur des types numériques et des opérateurs en Java.
    - Les opérateurs sont un exemple, mais pas le seul. Les spécificités des types primitifs sont également un problème pour la généricité de Java, qui ne marche que pour les objets. Il faut donc soit systématiquement boxer/unboxer les types primitifs (ce qu'on fait pour les collections), soit écrire jusqu'à 9 méthodes différentes au lieu d'une seule méthode générique (les streams de Java 8 ont des méthodes spécifiques pour les types int, long et double en plus des méthodes génériques).

    Citation Envoyé par thelvin Voir le message
    Et justement, ça n'a rien à voir avec les implémentations. C'est une question de définition du langage.
    C'est un problème d'implémentation qui est exposé dans la définition du langage. Ces types ont besoin d'être traités spécialement dans la JVM pour des raison de performance. Mais ont peut avoir des types primitifs dans le bytecode tout en ayant un langage "full-object" dans le code source. Java expose cette différence d'implémentation, là où Scala ou C# masquent les spécificités des types primitifs de la JVM ou du CLR.

    Citation Envoyé par thelvin Voir le message
    Il y a en Java, exactement 8 types primitifs. Pas moins, pas plus. 8. Pour certains d'entre eux, ça a un sens de prévoir un opérateur d'addition : double, float, long, int, short, byte et char. Pour d'autres, ça n'a pas de sens : boolean. Donc l'opérateur d'addition a été prévu pour les 7 types primitifs connus pour lesquels il a un sens, et pas pour les autres.

    BigInteger, par contre, est une classe. Une classe comme une autre. Il y a en Java un nombre indéfini de classes, ça change tout le temps. De manière générale, par exemple dans le cas chien + facture, un opérateur d'addition n'a pas de sens entre deux types classe, ou objet de manière générale. Il n'y a donc pas eu tentative d'insérer dans le langage un opérateur qui, par définition, ne peut pas marcher. Les méthodes, en revanche, sont des mécanismes qu'on peut appliquer à tous les types objet, donc si on a un type additionnable, il suffit de lui donner une méthode add().
    Il a été décidé pour le langage Java que la classe BigInteger, n'est pas si intéressante pour mériter d'être un cas particulier de sorte d'avoir un opérateur qui marche qu'avec elle. Même si ça avait été le cas, ça n'aurait pas résolu le besoin de nouvelles classes de nombres additionnables, dont Java ne pourrait pas deviner que ce sont des cas particuliers.
    Certaines classes, en Java, sont spéciales. Les classes wrappers. La classe String. La classe Object, ascendante de tous les types objets. Il y a une méthode qui est un xas particulier, aussi, getClass(). Mais pas BigInteger ni son add().
    Mon propos n'est pas de dire que BigInteger devrait avoir un traitement spécial, mais que les types primitifs ne devraient pas avoir un traitement spécial. Il n'y a pas besoin d'avoir un traitement spécial pour BigInteger pour qu'il puisse avoir un opérateur "+" - il suffit que le langage ait une syntaxe pour définir les opérateurs (comme en C#) ou ne différencie pas entre opérateurs et méthodes (comme en Scala).
    chien + facture est parfaitement légal dans ces langages, à condition que la classe de l'objet chien définisse une méthode "+" qui accepte en paramètre un type compatible avec le type de l'objet facture (ce qui ne sera jamais le cas, d'où erreur de compilation...).

  19. #19
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Il n'en reste pas moins que le prétexte n'est pas du tout une différence d'implémentation, mais bien de typage.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  20. #20
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 855
    Points
    22 855
    Billets dans le blog
    51
    Par défaut
    "utiliser des objets comme des primitifs"

    Hum, en fait c'est une manière déguisée de dire qu'on va pouvoir définir nos propres opérateurs (aux moins ceux de base) si j'ai bien saisi ?
    Car sinon je ne vois pas trop l'intérêt.

    *sous réserve que le langage aille effectivement dans cette direction.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

Discussions similaires

  1. Importer une classe java avec des paramétres dans JSP
    Par sky88 dans le forum Servlets/JSP
    Réponses: 18
    Dernier message: 30/06/2011, 10h20
  2. sérialisation XML en java Avec des Matrice ArrayList
    Par bilred dans le forum Collection et Stream
    Réponses: 7
    Dernier message: 16/04/2009, 15h55
  3. Réponses: 1
    Dernier message: 02/04/2009, 17h36
  4. Réponses: 4
    Dernier message: 23/03/2009, 11h20

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