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. #61
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 547
    Points : 21 602
    Points
    21 602
    Par défaut
    Ce n'est pas pour ton compte en banque, ça ils s'en fichent. C'est pour investir ton argent comme si c'était le leur, sans se faire arnaquer par l'endroit où ils l'investissent.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  2. #62
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par thelvin Voir le message
    - Mal sécurisé : Ben voyons, et par comparaison avec quel autre langage/architecture ?
    "Java c'est mal sécurisé", c'est le nouveau "Java c'est lent".

    Un gros mythe qui s'installe au vue des différentes news catastrophiques sur les problèmes de sécurité des applets.
    La plupart des gens n'arrivant pas à faire la distinction entre le plugin Java et le langage Java...


    a++

  3. #63
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 838
    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 838
    Points : 22 846
    Points
    22 846
    Billets dans le blog
    51
    Par défaut
    Citation Envoyé par jpiotrowski Voir le message
    On va bientôt arriver à des choses ésotériques qui ne seront faites que pour leur créateurs.
    Je reste cependant un poil attentif a ce point la.

    Depuis le passage au JDK8, outre le fait que parfois la syntaxe des streams peut s’avérer pas trop parlante / difficile a digérer par rapport a de simples boucles, je me suis plusieurs fois repris a devoir simplifier en urgence du code que j'avais écrits pour mes articles en préparation (articles qui sont plus destinés a des débutants / utilisateurs confirmés qu'a des experts).
    En effet, j'avais, sur le coup, abusé des lambdas, interfaces fonctionnelle et références de méthode et me trouvais a passer en paramètres de certains traitements devenus très génériques des allocateur, desallocateur, comparateur, etc. Donc, j’étais en train d’écrire en Java une sorte d’équivalents du code, très efficace mais totalement inabordable pour le néophyte, qu'on peut trouver dans ces bon vieux bouquins "The C++ Programming Language" de Stroustrup ou "Effective STL" de Meyers.

    Donc j'adore toutes ces nouvelles fonctionnalités mais j'ai de plus en plus l'impression d’écrire du C++ plutôt que du Java
    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

  4. #64
    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 bouye Voir le message
    Je reste cependant un poil attentif a ce point la.

    Depuis le passage au JDK8, outre le fait que parfois la syntaxe des streams peut s’avérer pas trop parlante / difficile a digérer par rapport a de simples boucles,
    ....
    Pour la question du fait que la syntaxe des steams est difficile à digéré par rapport au simples boucles, je ne pense pas. Moi je pense plutôt que c'est une question de maîtrise d'un nouveau paradigme qu'on avait pas en Java. Le même argument peut être donné par un fan du procédural devant l'Objet. Mais une fois on maîtrise l'objet on trouve moche de faire du procédural.

    Focaliser son esprit sur les boucles est pour moi n'est pas la bonne chose, car si on se dit que le but du programmeur est d'atteindre ces objectifs, à quoi ça sert vraiment se se focaliser sur le changement d'état que sur le comportement que j'attend de mon programme. Avec la programmation impérative je me soucis plus sur l’enchaînement des instructions de ma boucle, et le changement d'état de mes variables, que faire une fois j'ai tel donné dans tel valeur, et parfois avec plein d'indices surtout pour les boucles imbriqués dont le soucis est de savoir par quoi je dois initialisé, où la boucle va finir est ce que c'est i<n ou i<=n , j=i+1 ou j=i, j<i ou j<=i, des truc comme ça pour moi je ne pense pas que ça sert vraiment à quelque chose que de rendre la vie du développeur difficile au lieu de se concentrer sur les traitements que mon programme doit réaliser.

    La programmation fonctionnelle essaye de nous donner un autre mode de codage que l'impérative, il nous permet de regarder le programme comme un ensemble de comportement(fonctions) que mon programme évalue. Non seulement ça contribue fortement sur la sémantique de mon code du moment où il est simple de comprendre un programme fonctionnelle que des boucles dont il faut plein d'effort pour savoir vraiment le comportement, mais ça offre à mon programme plus de choix sur comment attaquer mon programme (évaluation paresseuses et autres..) et permet aussi de réduire le nombre de lignes de code à écrire, même si ce n'est pas toujours. Mais offre la facilité de l'intégration de la programmation parallèle.

    Donc pour moi c'est une question d'habitude et une bonne maîtrise du paradigme fonctionnel et puis c'est tout. Personnellement, je ne retournerais jamais aux boucles en Java que si je n'ai pas de choix. Je ne trouve aucune gêne d'abuser des expressions lambda et des référence de méthode (oui ça ressemble à C++ mais je vois pas la gêne) ils sont bon pour la santé du code que les classes anonymes.

  5. #65
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 627
    Points : 10 551
    Points
    10 551
    Par défaut
    Citation Envoyé par la.lune Voir le message
    Focaliser son esprit sur les boucles est pour moi n'est pas la bonne chose, car si on se dit que le but du programmeur est d'atteindre ces objectifs, à quoi ça sert vraiment se se focaliser sur le changement d'état que sur le comportement que j'attend de mon programme. Avec la programmation impérative je me soucis plus sur l’enchaînement des instructions de ma boucle, et le changement d'état de mes variables, que faire une fois j'ai tel donné dans tel valeur, et parfois avec plein d'indices surtout pour les boucles imbriqués dont le soucis est de savoir par quoi je dois initialisé, où la boucle va finir est ce que c'est i<n ou i<=n , j=i+1 ou j=i, j<i ou j<=i, des truc comme ça pour moi je ne pense pas que ça sert vraiment à quelque chose que de rendre la vie du développeur difficile au lieu de se concentrer sur les traitements que mon programme doit réaliser.
    Je ne sais pas vraiment si c'est de cela dont tu parles, mais tu oublies un [gros] truc

    En C, il n'y a qu'une seule façon simple de créer des tableaux avec les crochets []: mais cela crée en gros un bloc contiguë en mémoire.
    Donc 1 seule façon de le parcourir de 0 à N.

    Mais en POO, les collections sont plus complexes, mais elles sont nettement plus flexibles et nettement plus adaptées aux besoins.
    Mais les données ne sont pas contiguës en mémoire. Donc on est obligé de passer par une classe itérateur spécifique à chaque collection parce qu'elle seule sait comment parcourir la collection.

    D’ailleurs cela se voit que tu n'as jamais travaillé avec des fichiers (images, vidéos, ...), parce que pour parser les headers, tu es obligé de faire des boucles pour récupérer les différentes informations

    Citation Envoyé par la.lune Voir le message
    La programmation fonctionnelle essaye de nous donner un autre mode de codage que l'impérative
    Non la première raison des fonctions c'est de regrouper les traitement afin d'être appelés plusieurs fois, et non pas faire des copier/ collé ou des GOTO

  6. #66
    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 : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par foetus Voir le message
    En C, il n'y a qu'une seule façon simple de créer des tableaux avec les crochets []: mais cela crée en gros un bloc contiguë en mémoire.
    Donc 1 seule façon de le parcourir de 0 à N.

    Mais en POO, les collections sont plus complexes, mais elles sont nettement plus flexibles et nettement plus adaptées aux besoins.
    Mais les données ne sont pas contiguës en mémoire. Donc on est obligé de passer par une classe itérateur spécifique à chaque collection parce qu'elle seule sait comment parcourir la collection.
    En C aussi, tu peux avoir des collections plus complexes qu'un simple tableau, pour définir une collection (liste, pile, etc.) tu n'as même pas besoin d'OO, l'encapsulation et une forme de généricité [1][2] suffisent.

    La grosse différence ici entre le C et les langages plus récent (et objet) n'est pas l'objet mais l'existence d'une bibliothèque standard plus riche (et une bibliothèque standard plus riche qu'en C, ce n'est pas bien difficile ;-))

    Citation Envoyé par foetus Voir le message
    D’ailleurs cela se voit que tu n'as jamais travaillé avec des fichiers (images, vidéos, ...), parce que pour parser les headers, tu es obligé de faire des boucles pour récupérer les différentes informations
    J'ai vraiment du mal à voir le lien entre le parsing d'une en-tête de fichier et les boucles. C'est quand même rarement répétitif une en-tête.

    Au passage, la récursion ça existe aussi et est, pour faire simple, encouragée en fonctionnelle. Il y a certes des contraintes techniques derrière mais bon au temps pour l'obligation des boucles.

    Citation Envoyé par foetus Voir le message
    Non la première raison des fonctions c'est de regrouper les traitement afin d'être appelés plusieurs fois, et non pas faire des copier/ collé ou des GOTO
    Le rapport entre la programmation fonctionnelle et le fait de faire des fonctions pour regrouper les traitements appelés plusieurs fois ? Ne confondrais-tu pas procédurale et fonctionnelle ici ?




    [1] Y compris, dans le pire des cas, un type de base qu'il s'appelle object ou void*.
    [2] Et dans ce cas précis, un bon polymorphisme paramétrique est amplement mieux que de l'OO.

  7. #67
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 627
    Points : 10 551
    Points
    10 551
    Par défaut
    Citation Envoyé par gl Voir le message
    La grosse différence ici entre le C et les langages plus récent (et objet) n'est pas l'objet mais l'existence d'une bibliothèque standard plus riche (et une bibliothèque standard plus riche qu'en C, ce n'est pas bien difficile ;-))
    Tu peux presque rajouter le C++ avec le C


    Citation Envoyé par gl Voir le message
    J'ai vraiment du mal à voir le lien entre le parsing d'une en-tête de fichier et les boucles. C'est quand même rarement répétitif une en-tête.
    Je pensais aux fichiers MP4. Tu as une table de "où se trouvent les chunks" pour chaque piste (si je ne me trompe pas, et même une table de tailles de chunks).
    Donc tu as beau avoir des liste/ deque/ map/ ..., il faut faire une jolie boucle

    Et aussi, avec le ID3 V2 (si je ne me trompe pas) où les données ne sont pas fixes, mais on te donne la taille avant [même si on n'est pas obligé de lire caractère par caractère]

    Citation Envoyé par gl Voir le message
    Au passage, la récursion ça existe aussi et est, pour faire simple, encouragée en fonctionnelle. Il y a certes des contraintes techniques derrière mais bon au temps pour l'obligation des boucles.
    La seule contrainte c'est la taille de la pile

    Citation Envoyé par gl Voir le message
    Le rapport entre la programmation fonctionnelle et le fait de faire des fonctions pour regrouper les traitements appelés plusieurs fois ? Ne confondrais-tu pas procédurale et fonctionnelle ici ?
    Tu veux dire procédurale: listing vers fonctions, et fonctionnelle: Objet vers fonctions

    Moi je fais beaucoup de C++ et donc les pointeurs de fonctions, les foncteurs, la surcharge des opérateurs, l'absence de notion d'interface (même s'il y a les virtuelles pures) [on a même la notion d'amitié pour accéder d'une fonction/ classe aux parties d'une autre classe] c'est tellement naturel que je dois confondre les termes.

  8. #68
    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 foetus Voir le message
    Je ne sais pas vraiment si c'est de cela dont tu parles, mais tu oublies un [gros] truc

    En C, il n'y a qu'une seule façon simple de créer des tableaux avec les crochets []: mais cela crée en gros un bloc contiguë en mémoire.
    Donc 1 seule façon de le parcourir de 0 à N.

    Mais en POO, les collections sont plus complexes, mais elles sont nettement plus flexibles et nettement plus adaptées aux besoins.
    Mais les données ne sont pas contiguës en mémoire. Donc on est obligé de passer par une classe itérateur spécifique à chaque collection parce qu'elle seule sait comment parcourir la collection.

    D’ailleurs cela se voit que tu n'as jamais travaillé avec des fichiers (images, vidéos, ...), parce que pour parser les headers, tu es obligé de faire des boucles pour récupérer les différentes informations
    Euh ... Quoi? Ce n'est pas de cela que je parle et je trouve que tu passes vraiment à coté. Quel est la liaison entre le fait de ne pas utiliser des boucles et le fait de laisser les tableaux? L'API Stream de Java 8 n'est pas fait que pour les collection, on peut ouvrir un flux sur un tableau et manipuler comme on veut, pas de copie, tous les éléments du tableaux restent contiguës comme en C. Il n'était pas question de jeter les tableaux à côté.

    Moi je dis tout simplement qu'au lieu par exemple de chercher le maximum d'un tableau utiliser une boucle je préfère faire de la programmation fonctionnelle. Donc au lieu d'avoir à faire:
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int tab[]=new int[]{12,14,15,17,28,12,13,60,3,4,7};
    int max=Integer.MIN_VALUE;
     
    for(int i=0;i<tab.length;i++){
     
               max=Math.max(max,tab[i]);
     
           };
    Je peux le traduire exactement comme ça
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int tab[]=new int[]{12,14,15,17,28,12,13,60,3,4,7};
    int max=IntStream.of(tab)
                     .reduce(Integer.MIN_VALUE,Math::max);
    Bon il y a déjà une méthode pour ça
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    nt tab[]=new int[]{12,14,15,17,28,12,13,60,3,4,7};
    int max=IntStream.of(tab)
                     .max()
                     .getAsInt();
    Et si je veux afficher tous les éléments
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    IntStream.of(tab).forEach(it->{
                       out.println(it);});
    //vu que la méthode println a besoin d'une seule entrée qui est l’élément en cours je peux faire
    IntStream.of(tab).forEach(out::println);
    La 2e des chose je n'ai pas dis aussi que je peux tout faire avec du fonctionnel, j'ai dis que je n'utiliserais pas les boucles quand j'ai le choix, et c'est tout.
    Non la première raison des fonctions c'est de regrouper les traitement afin d'être appelés plusieurs fois, et non pas faire des copier/ collé ou des GOTO
    Est ce que tu comprend ce que je veux dire? Moi je ne suis pas entrain de définir pourquoi une fonction, mais je parle du paradigme fonctionnel, sa philosophie, comment je dois considérer un programme.

  9. #69
    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 : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par foetus Voir le message
    Je pensais aux fichiers MP4. Tu as une table de "où se trouvent les chunks" pour chaque piste (si je ne me trompe pas, et même une table de tailles de chunks).
    Donc tu as beau avoir des liste/ deque/ map/ ..., il faut faire une jolie boucle

    Et aussi, avec le ID3 V2 (si je ne me trompe pas) où les données ne sont pas fixes, mais on te donne la taille avant [même si on n'est pas obligé de lire caractère par caractère]
    Oui des entête contenant des "listes", ça existe mais ça reste assez rare.
    C'est par contre bien plus fréquent au sein des données ou d'avoir un ensemble d'entête/données dans le cas de fichier conteneur.

    Citation Envoyé par foetus Voir le message
    La seule contrainte c'est la taille de la pile
    Une contrainte oui, la seule non.

    L'optimisation de récursion terminale est une optimisation très fréquence; par contre ça contraint d'implémenter sous forme terminale et ça limite aux langages et/ou implémentations qui supporte cette optimisation (et donc limite la portabilité).

    Sans cette optimisation, même en restant dans une plage d'utilisation ne dépassant pas la taille de la pile, la récursion à un coût temporel et spatial différent des versions itératives.

    Et encore c'est sans parler de l'expressivité et de la proximité avec le domaine modélisé.

    Citation Envoyé par foetus Voir le message
    Tu veux dire procédurale: listing vers fonctions, et fonctionnelle: Objet vers fonctions
    Objet et fonctionnel c'est assez orthogonal (on peut avoir de l'objet non fonctionnel, du fonctionnel non objet mais aussi du fonctionnel objet).
    Mais je pense que tu ne l'emploies pas le terme "programmation fonctionnelle" dans son sens usuel, comment définis-tu ce terme ?

    Citation Envoyé par foetus Voir le message
    Moi je fais beaucoup de C++ et donc les pointeurs de fonctions, les foncteurs, la surcharge des opérateurs, l'absence de notion d'interface (même s'il y a les virtuelles pures) [on a même la notion d'amitié pour accéder d'une fonction/ classe aux parties d'une autre classe] c'est tellement naturel que je dois confondre les termes.
    Le C++ possède certes des traits fonctionnels (et ça va croissant), permet de programmer dans un esprit un peu fonctionnel et il y a même une inspiration fonctionnelle dans la SL, notamment sur les algorithmes (avec des noms peu usuels), mais je ne le qualifierais pas de fonctionnel. Il a clairement une orientation impérative.

  10. #70
    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 : 38
    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 083
    Points
    7 083
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    les variables primitives Java deviendraient peut-être des classes, et peut-être que les Wrapper ne seront plus utilisés. Bien sur coté performance il y aura certainement un impact négatif.
    Pourquoi aurait un impact sur les performances ? Rien d'empêche le compilateur de transformer un 5.plus(6) en un bête 5 + 6 à la compilation en ByteCode ou bien en langage machine (JIT). Au moins pour les types primitifs. Pour les fonctions plus complexes, il pourrait soit appeler une sorte de méthode statique, soit "inliner" la fonction.

    Citation Envoyé par Gugelhupf Voir le message
    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.
    Pareillement, "new" est un concept d'allocation dans le tas (heap) et non sur la pile (stack). Néanmoins on perdrait le concept de non-initialisé/absence de valeur (null).

    Néanmoins, j'émet un gros doute sur le fait de rajouter une nouvelle "classe" de type. Les objets et les primitifs cohabitent déjà assez mal. Je préfère les travaux récents qui "permettent" l'allocation des objets sur la pile au lieu du tas lorsque cela est possible sans risque.

    Citation Envoyé par Gugelhupf Voir le message
    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
    il y a aussi :
    • Des transpileurs COBOL -> Java. Pour le peu de complexité des programmes COBOL, il ne doit pas y avoir de grosses difficultés en dehors des affreux couples GOTO/PERFORM UNTIL.
    • Souvent complètement démotivés, plus intéressés par leurs avantages sociaux antédiluviens et leurs futures pré-retraites. Les banques feraient de grandes économies à former les plus motivés et embaucher des petits jeunes. D'ailleurs c'est ce qu'ils sont entrain de faire, mais pour le moment les nouveaux font encore du COBOL et servent surtout à redynamiser les équipes plus que vieillisantes (moyennes d'âge > 45 ans par endroit)
    • Ca tombe bien IBM fournie sa propre JVM qui tourne sur z/OS ainsi que des drivers pour DB2

    En revanche pour les JCLs, je ne sais pas trop si c'est transpilable facilement.

    Citation Envoyé par Gugelhupf Voir le message
    Ils devraient plutôt faire usage du mot-clé "struct"
    Exactement ce à quoi je pensais en lisant la news

    Citation Envoyé par Gugelhupf Voir le message
    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é...
    C'est surtout que ces types ne sont pas polymorphe (question d'optimisation). Il n'y a pas de résolution de méthode à faire.

    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
    Le problème ce sont les conversions implicites dans tous les sens. Je me souviens d'un code qui lit un double depuis la base de données, le stock en Double dans l'entité (objet lié à la base de données), puis il passe en double dans une couche et ainsi de suite sur une dizaine d'appel pour finir en double. Et je suis pas certains que l'autoboxing renvoie toujours une valeur en cache, dans ce cas je compte pas le nombre d'allocations effectuées pour rien ; d'autant plus si la méthode est appelée excessivement souvent !

    Citation Envoyé par la.lune Voir le message
    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
    En Ceylon, ils ont autorisé la redéfinition d'opérateurs en exploitant les opérateurs comme du sucre syntaxique et un couple interface/méthode dédié. Par exemple, on pourrait avoir Summable avec une méthode add. Le code a + b est simplement pré-compilé en a.add(b). Charge ensuite au processus normale de compilation de résoudre la méthode et de vérifier la signature.

    Citation Envoyé par la.lune Voir le message
    vaut mieux avoir partout des références sur le tas, avec une inférence de type très fort.
    Le tas a plusieurs inconvénients : plus long à lire (il faut résoudre l'adresse et éventuellement charger la page mémoire, etc.), plus long à nettoyer (il faut faire intervenir les algorithmes du GC), plus de contrôle (cache, remise en mémoire centrale, etc.). Alors que sur la pile, t'es sûr de ne pas partagé l'info avec un autre thread et une fois la frame consommée tu peux tout détruire.

    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.
    "+" a un sens en algèbre de Boole. Et l'opérateur existe aussi pour les String !

    Citation Envoyé par thelvin Voir le message
    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().
    C'est pourquoi elles sont dans le package "java.lang" Ce package fait partie du langage et n'est pas simplement une API.

    Citation Envoyé par Cyäegha Voir le message
    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.
    Il y tout de même une différence énorme. Ces types ne sont pas polymorphes et ce sont biens des "valeurs", ainsi on considère que la notion d'identité n'existe pas, comme pour les primitifs et contrairement aux objets. Il est donc probable que ces types pourront "jouer" avec les opérateurs mais ce ne seront pas des objets.
    Il ne faut donc pas oublier que quand ces objets se retrouveront sur le tas, ils seront dupliqués à chaque affectation et les incidences sur la mémoire seront à prendre en considération. Ce qui m'effraie d'ailleurs c'est qu'on y accore autant d'importance qu'au boxing, c'est-à-dire aucune.

    Citation Envoyé par Cyäegha Voir le message
    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).
    Ou alors "n" versions de la même classe. Par exemple, si tu veux créer interface de map de caractère, tu devras créer une nouvelle interface (et implémentation) si tu veux faire de même avec un autre primitif. Les Atomic* en sont un exemple.

    Citation Envoyé par la.lune Voir le message
    Non pas forcement à quoi ça sert l’inférence de type mais la fonction possède un type de retour non? Il va obligatoirement me refuser de retourner quelque chose qui ne correspond pas au type c'est simple je je retourne (100,2), quand même il sait vérifier que le type de retour est un décimal et qu'il existe un constructeur qui prend deux paramètres dont deux entier, de la même manière qu'il ne refuse pas de faire decimal salary=(100,3) il va accepter les deux valeur entre parenthèses et tout est réglé. La JVM sait faire de l’inférence de type depuis l'entrée des generic et maintenant avec les lambda il sait bien reconnaître les types des paramètres des fonction.
    return (100,3) je trouve ça assez moche. On a l'impression de ne pas savoir de quoi on parle.

    Citation Envoyé par la.lune Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    final class Point(int x, int y){ //Le reste se fait automatiquement x et x sont public
    private int c;//Si je veux avoir une valeur privé
    boolean equals(Point p){
    return this.x==p.x&&this.y==p.y}
    public static Point manipuler(){
    int a; int b;
    //traitement
    return (a,b); //inférence de type
    }
    public static void maFunction(Point p, boolean b, double b){
    //traitement
    }
    } 
    final class MaClass(char a, double f, boolean b){
    }//ça peut suffir déjà, si c'est pour manipuler un value Type de maClass
    • "final" et "class" sont à banir à mon avis. Comme pour les "enum", il faut un mot clé spécifique. D'ailleurs les énumérations sont des formes de "value". Mes choix porteraient sur "value" ou "struct".
    • Toujours en me basant sur les énumérations, je pense qu'on devrait pouvoir avoir des "constructeurs". Et la signature du(es) constructeur(s) ne devrai(en)t pas créé d'attribut correspondant. La représentation interne pouvant être bien différente de ce qu'on expose. Par exemple, un vecteur peut-être initialisé avec des degrés ou des radiants ; mais on ne choisira qu'une seule représentation pour l'implémenter.


    Citation Envoyé par la.lune Voir le message
    Point p1=(2,4),p2=(5,6),p3=(2,4);
    Bon pourquoi pas mais je suis pas fan, je préfère répéter le type et utiliser une minuscule pour le nom du type.

    Citation Envoyé par la.lune Voir le message
    boolean b2=p1==(2,4);
    Un exemple parfait ou je trouve que la syntaxe n'est pas judicieuse. C'est tout de même plus lisible : boolean b2= p1 == point(2,4);
    Citation Envoyé par la.lune Voir le message
    boolean b2=(2,4)==p1; : Possible de faire de l’inférence de type mais en fait il faut qu'on sache que c'est la fonction equals qui est appelé alors ça sera moche qu'en compilation il va transformer (2,4)==p1 en p1.equals((2,4)) ou tout simplement il va créer une nouvelle Value Type
    boolean b4=(2,4)==(2,4) : pas de base pour une inférence de type
    Aucun problème d'inférence si on utilisait la syntaxe complète.

    Citation Envoyé par la.lune Voir le message
    maFunction((3,5),true,2.4);
    Par ailleurs comment inférer sur ce type de signatures :
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    public void faire(point p);
    public void faire(vecteur v);

    Citation Envoyé par la.lune Voir le message
    Point2D p=(Point2D)(Point)(2,3);
    Les types des valeurs doivent être finaux et non polymorphes ainsi le "casting" n'existe pas ; à voir si on autorise une "conversion". Comme pour les primitifs.

    Citation Envoyé par la.lune Voir le message
    Qui me dit que decimal n'est pas une fonction qui prend deux entier?
    De la même manière qu'on résout actuellement deux conflits équivalents :
    1. Deux classes avec le même nom de base
    2. Un import static qui a le même nom qu'un membre "local" ou un autre import static

    La réponse : on utilise le nom complet. Exemple : com.developpez.java.point

    Citation Envoyé par la.lune Voir le message
    Sinon comment créer des méthodes qui vont manipuler des matrices et autre vu qu'on a pas de pointeur en Java.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public static Matrix10x10 calcule(Matrix10x10 m1,Matrix10x10 m2){}
    Tu sais @atha si ce que tu dis est vrai, une simple appellation de cette méthode calcule exigera une copie de tous les éléments de m1, et m2, et une fois retourner quelque chose ça ne va pas retourner la matrice qui est crée à l'intérieur de la fonction et utilisé pour retourner mais encore une copie de toute la matrice résultant
    Jamais une chose pareil aura lieu en Java.
    C'est bien le choix effectué en C/C++. C'est d'ailleurs tout l'intérêt du final de C/C++ car cela assure que la référence n'est pas mutée et donc qu'on peut y passer l'adresse de "l'objet" passé en paramètre (y compris l'adresse sur la pile). Après si les "values" ne sont pas mutables, la JVM sait qu'elle peut partager les références pour les "traitements" qui ne partagent pas de données de la pile vers le tas.
    Par exemple, si je créés une "value type" dans le corps d'une méthode, elle est initialisée dans le tas. Si je veux l'affecter via un "setter" dans un bean, lors du passage par paramètre, la JVM se contente de donner l'adresse sur la pile. Par contre au moment de l'affectation à l'attribut, la valeur sera bien entièrement recopiée dans le tas.
    A contrario, si je prends une valeur depuis un attribut (depuis le tas donc), je peux partager la même référence aussi bien sur la pile que le tas.
    En revanche, il reste un cas compliqué où je ne pense pas que la JVM puisse beaucoup inférer :
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    point p = point(1,2);
    List<point> liste = new ArrayList<>();
    liste.add(p);
    liste.add(p);
    La valeur sera copiée deux fois dans le tas.

    Par ailleurs, quand tu fais List<String,String> newList = new LinkedList<>(bigList); tu vas bien créer une grande quantité d'objet pour gérer la grande taille de la liste. Et il ne me viendrait pas à l'idée de créer une matrice en tant que "value" (sachant la gestion spécifique de la mémoire liée à celles-ci).

    Citation Envoyé par adiGuba Voir le message
    Ce problème est évoqué dans la proposition, à la fin de la section "General approach: usage" :
    A fourth aspect of primitives is that, although they do not have values that correspond to the null reference, they do have default values, generally some sort of zero. This default value shows up in the initial contents of uninitialized fields and array elements. It is therefore necessary to specify a default value for each value type. The simplest default composite value is the one which which is recursively default in all of its subfields. Given that predefined default values are a fixture in Java, this convention does not appear harmful, so we will adopt it.

    As a result, the author of methods in a value type definition will need provide behavior to default (all-zero-bits) values, even if the constructors never create them, since they can be observed in some uninitialized variables. It is likely that we will either forbid no-argument constructors or require them to produce default values, to avoid “duelling defaults”.
    Dommage ils auraient éventuellement pu délégué à un constructeur par défaut. Et à défaut d'en définir un il pourrait avoir ce comportement. Là potentiellement on créé une valeur qui pourrait être "hors limite". Je m'exprime autrement : imaginons un type de valeur "Entier strictement positif", alors la valeur d'initialisation sera une valeur hors limite. Même si cet état à vocation à être temporaire, j'aime en tant que concepteur que mes pre-conditions soient toujours vraies ; sauf exceptionnellement dans le cas d'un état transitoire MAIS interne.
    Hors là l'état transitoire serait induit par la gestion d'un cycle de vie externe. En d'autres mots, la phase "initialisation" du type utilisateur provoque un état, interne à MON type, temporaire et incohérent.

    Citation Envoyé par bouye Voir le message
    je me suis plusieurs fois repris a devoir simplifier en urgence du code que j'avais écrits pour mes articles en préparation (articles qui sont plus destinés a des débutants / utilisateurs confirmés qu'a des experts).
    En effet, j'avais, sur le coup, abusé des lambdas, interfaces fonctionnelle et références de méthode et me trouvais a passer en paramètres de certains traitements devenus très génériques des allocateur, desallocateur, comparateur, etc. Donc, j’étais en train d’écrire en Java une sorte d’équivalents du code, très efficace mais totalement inabordable pour le néophyte, qu'on peut trouver dans ces bon vieux bouquins "The C++ Programming Language" de Stroustrup ou "Effective STL" de Meyers.
    Dans ce cas le problème n'est pas Java mais ton API. Une API peut-être complexe à manipuler si la problématique qu'elle couvre est complexe. Mais rien n'empêche d'en faire une version/surcouche plus simple. C'est d'ailleurs l'enjeu de l'objet. Avoir des "interfaces de communications" (ie méthodes) "simples" alors que les traitements internes peuvent être complexes.
    Ou comment redéfinir les patterns FlyWeight, Facade et consort.

    Quand je lis ça, je lis juste : "j'ai dû créer un code complexe pour couvrir un algorithme complexe d'un problème complexe". D'un point de vue de programmeur, je n'y vois aucune aberration. D'un point de vue de concepteur ou architecteur de code, ca peut ouvrir une discussion comme étant tout à fait banale. Et pour un concepteur de langage (ou d'outil de manière générale), mon objectif sera la première affirmation : "ca ne doit pas être aberrant pour l'utilisateur".
    Pour faire une dernière analogie, ton code peut-être complexe (que se soit justifié ou pas), il en demeure pas moins que l'utilisation du logiciel doit être simple pour l'utilisateur.

    Concernant les fonctions récursives :
    Citation Envoyé par foetus Voir le message
    La seule contrainte c'est la taille de la pile
    Ce n'est ni une condition nécessaire, ni suffisante. D'ailleurs tous les travaux autour des langages fonctionnels, reposent sur le principe de la "récursion à gauche" (il me semble que c'est le terme mais pas sûr). Le principe est justement de remplacer de nombreux empilements par une forme de "linéarisation" à l'exécution. De sortes qu'il n'y a pas besoin d'avoir atteint le "bout" de la pile d'appel (et donc d'empiler les appels) pour calculer le résultat.
    Ainsi on optimise l'utilisation de la pile, les copies, les allocations, etc. D’où parfois des performances très intéressantes en utilisant conjointement une écriture optimisée, des types non-mutants et la forme "fonctionnelle".
    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

  11. #71
    Membre chevronné
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Points : 1 855
    Points
    1 855
    Par défaut
    Citation Envoyé par Nemek Voir le message
    il y a aussi :
    • Souvent complètement démotivés, plus intéressés par leurs avantages sociaux antédiluviens et leurs futures pré-retraites. Les banques feraient de grandes économies à former les plus motivés et embaucher des petits jeunes. D'ailleurs c'est ce qu'ils sont entrain de faire, mais pour le moment les nouveaux font encore du COBOL et servent surtout à redynamiser les équipes plus que vieillisantes (moyennes d'âge > 45 ans par endroit)
    <remarque sans rapport avec la discussion technique>
    ayant personnellement dépassé 65 ans la remarque associant une moyenne d'age > 45 ans à "vieillissant'" m'a fait tiquer.
    Je raconte toujours l'histoire d'un de mes anciens élèves: ayant dépassé 45 ans et la boite qui l'employait ayant fait faillite il ne trouvait plus d'emploi: "trop vieux"!
    de rage il a passé l'aggrégation de maths et l'a eu avec les honneurs du premier coup -> trop vieux?
    j'ai aussi formé à Java d'anciens Coboliaques et ils sont comme les plombiers/zingueurs ou les politiciens: il y en a des bons et des mauvais.... on ne peut pas prévoir
    Comme dit la chanson de Brassens : "l'age n'y fait rien à l'affaire ...."
    </remarque sans rapport avec la discussion technique>
    J'ai des principes: je peux toujours trouver une bonne raison pour les contredire .... mais j'ai des principes!
    (mon excellent bouquin sur Java : https://eska-publishing.com/fr/livre...822407076.html)

  12. #72
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 547
    Points : 21 602
    Points
    21 602
    Par défaut
    Citation Envoyé par Nemek Voir le message
    Citation Envoyé par Gugelhupf
    les variables primitives Java deviendraient peut-être des classes, et peut-être que les Wrapper ne seront plus utilisés. Bien sur coté performance il y aura certainement un impact négatif.
    Pourquoi aurait un impact sur les performances ? Rien d'empêche le compilateur de transformer un 5.plus(6) en un bête 5 + 6 à la compilation en ByteCode ou bien en langage machine (JIT). Au moins pour les types primitifs. Pour les fonctions plus complexes, il pourrait soit appeler une sorte de méthode statique, soit "inliner" la fonction.
    Je dirais que le problème, c'est que les types objets, en Java, peuvent prendre la valeur null. Et que les primitifs, dans leur fonctionnement actuel, en sont incapables sans un wrapper.
    Du code cherchant à traiter des entiers selon la dualité primitif/objet, se retrouvera donc à devoir d'une manière ou d'une autre représenter si oui ou non l'objet est null, et si non sa valeur. Ce qui fait de la mémoire à gérer en plus et des vérifications en plus. Alors que l'idée des types primitifs, c'est de voir leur valeur directement sans indirection.

    Citation Envoyé par Nemek Voir le message
    "+" a un sens en algèbre de Boole.
    Mais il est très impopulaire en algorithmique générale.

    Normal. Dans le code if(isRaining + hasUmbrella) on a l'impression qu'on essaie d'additionner quelque chose, alors que dans le code if(isRaining || hasUmbrella) déjà on voit qu'on additionne rien et après deux jours de formations à la programmation, on sait y voir un OU logique.

    Citation Envoyé par Nemek Voir le message
    Et l'opérateur existe aussi pour les String !
    Qui est un type objet donc pas primitif, et aucune autre classe n'a cet opérateur. Effectivement, la classe String profite d'un traitement particulier dans le langage, notamment un opérateur +. Les autres classes n'en ont pas.
    "Les autres classes" incluant donc BigInteger. On parlait pas d'autre chose au départ.

    Citation Envoyé par Nemek Voir le message
    Dommage ils auraient éventuellement pu délégué à un constructeur par défaut.
    Ça aurait été souhaitable pour l'idéal, mais incroyablement impactant pour l'existant. Jusque-là l'initialisation n'avait qu'à mettre 0, false ou null, et maintenant on lui demande d'aller chercher et invoquer des constructeurs ? C'est pas le même boulot, c'est pas le même format, c'est pas les mêmes garanties en temps, en espace et en cohérence mémoire ! Parce que bon, on sait bien qu'en réalité, la JVM initialise la mémoire à zéro et basta. Ça fait 0, false et null comme ça doit.

    Alors effectivement on aurait préféré, mais damn, le bytecode et sa gestion n'ont juste plus rien à voir, bon courage pour la migration.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  13. #73
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 838
    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 838
    Points : 22 846
    Points
    22 846
    Billets dans le blog
    51
    Par défaut
    Citation Envoyé par Nemek Voir le message
    Citation Envoyé par bouye Voir le message
    je me suis plusieurs fois repris a devoir simplifier en urgence du code que j'avais écrits pour mes articles en préparation (articles qui sont plus destinés a des débutants / utilisateurs confirmés qu'a des experts).
    En effet, j'avais, sur le coup, abusé des lambdas, interfaces fonctionnelle et références de méthode et me trouvais a passer en paramètres de certains traitements devenus très génériques des allocateur, desallocateur, comparateur, etc. Donc, j’étais en train d’écrire en Java une sorte d’équivalents du code, très efficace mais totalement inabordable pour le néophyte, qu'on peut trouver dans ces bon vieux bouquins "The C++ Programming Language" de Stroustrup ou "Effective STL" de Meyers.
    Dans ce cas le problème n'est pas Java mais ton API. Une API peut-être complexe à manipuler si la problématique qu'elle couvre est complexe. Mais rien n'empêche d'en faire une version/surcouche plus simple. C'est d'ailleurs l'enjeu de l'objet. Avoir des "interfaces de communications" (ie méthodes) "simples" alors que les traitements internes peuvent être complexes.
    Ou comment redéfinir les patterns FlyWeight, Facade et consort.

    Quand je lis ça, je lis juste : "j'ai dû créer un code complexe pour couvrir un algorithme complexe d'un problème complexe". D'un point de vue de programmeur, je n'y vois aucune aberration. D'un point de vue de concepteur ou architecteur de code, ca peut ouvrir une discussion comme étant tout à fait banale. Et pour un concepteur de langage (ou d'outil de manière générale), mon objectif sera la première affirmation : "ca ne doit pas être aberrant pour l'utilisateur".
    Pour faire une dernière analogie, ton code peut-être complexe (que se soit justifié ou pas), il en demeure pas moins que l'utilisation du logiciel doit être simple pour l'utilisateur.
    Complexe non, c'est même d'une logique assez simple que de créer des tas et des tas de nouvelles micro-classes et interfaces fonctionnelles génériques destinés a des usages bien précis et spécifiques comme le faisait la STL de C++ déjà, bien avant que Java ne s'y mette. Ça n'en reste pas moins illisible pour autant. Or un code illisible n'est pas aisément maintenable, encore plus lorsqu'on le confie a des débutants.
    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

  14. #74
    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 : 38
    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 083
    Points
    7 083
    Par défaut
    <remarque sans rapport avec la discussion technique>
    Citation Envoyé par professeur shadoko Voir le message
    ayant personnellement dépassé 65 ans la remarque associant une moyenne d'age > 45 ans à "vieillissant'" m'a fait tiquer.
    Je raconte toujours l'histoire d'un de mes anciens élèves: ayant dépassé 45 ans et la boite qui l'employait ayant fait faillite il ne trouvait plus d'emploi: "trop vieux"!
    de rage il a passé l'aggrégation de maths et l'a eu avec les honneurs du premier coup -> trop vieux?
    Loin de moi de vouloir être insultant. Je suis pas statisticien, sociologue, psychologue, etc. mais simple observateur.
    Je préfère précisez que je ne pense pas que toutes les personnes < 45 ans sont comme ci, que celles entre 45 et 65 autrement et enfin celles de > 65 encore autrement. Néanmoins, il faut avouer qu'il y a des généralités et qu'elles sont à prendre pour ce qu'elles sont : "En général, blablabla".
    En l’occurrence, j'évoquais des cas très concrets d'équipes complètement démotivés car proche de la retraite (désolé si à 45 ans on est plus proche de la retraite qu'à 30) et sur-avantagés. Et que la mixité sociale/culturelle/générationnelle est bénéfique pour une équipe (de développement ou pas). Car ne jetons pas le bébé avec l'eau du bain.

    </remarque sans rapport avec la discussion technique>


    Citation Envoyé par thelvin Voir le message
    Je dirais que le problème, c'est que les types objets, en Java, peuvent prendre la valeur null. Et que les primitifs, dans leur fonctionnement actuel, en sont incapables sans un wrapper.
    Du code cherchant à traiter des entiers selon la dualité primitif/objet, se retrouvera donc à devoir d'une manière ou d'une autre représenter si oui ou non l'objet est null, et si non sa valeur. Ce qui fait de la mémoire à gérer en plus et des vérifications en plus. Alors que l'idée des types primitifs, c'est de voir leur valeur directement sans indirection.
    Et qui dit que la valeur "null" doit être acceptable pour un primitif ? Au pire ca ne fait qu'un état (et de la mémoire) supplémentaire à gérer.

    Citation Envoyé par thelvin Voir le message
    Mais il est très impopulaire en algorithmique générale.
    Normal. Dans le code if(isRaining + hasUmbrella) on a l'impression qu'on essaie d'additionner quelque chose, alors que dans le code if(isRaining || hasUmbrella) déjà on voit qu'on additionne rien et après deux jours de formations à la programmation, on sait y voir un OU logique.
    Qui est un type objet donc pas primitif, et aucune autre classe n'a cet opérateur. Effectivement, la classe String profite d'un traitement particulier dans le langage, notamment un opérateur +. Les autres classes n'en ont pas.
    "Les autres classes" incluant donc BigInteger. On parlait pas d'autre chose au départ.
    Les deux exemples étaient juste pour souligner que rien ne motive réellement le choix de ne pas permettre la définition d'opérateur sur d'autres type et notemment BigInteger.

    Citation Envoyé par thelvin Voir le message
    Ça aurait été souhaitable pour l'idéal, mais incroyablement impactant pour l'existant. Jusque-là l'initialisation n'avait qu'à mettre 0, false ou null, et maintenant on lui demande d'aller chercher et invoquer des constructeurs ? C'est pas le même boulot, c'est pas le même format, c'est pas les mêmes garanties en temps, en espace et en cohérence mémoire ! Parce que bon, on sait bien qu'en réalité, la JVM initialise la mémoire à zéro et basta. Ça fait 0, false et null comme ça doit.
    J'avoue que c'est pas clean. Mais rien n'empêche d'initialiser tout à 0, puis d'invoquer le constructeur des "valeurs". Néanmoins, je pense que les motivations sont louables :
    1. Les performances : pas de traitement à localiser et exécuter ;
    2. C'est à priori un état très temporaire et la variable n'est pas censée être manipulée durant cette phase transitoire ;
    3. C'est un état supposé connu/admis/compris par le développeur Java qui a donc la charge de prendre les précautions qui s'imposent.


    Citation Envoyé par bouye Voir le message
    Complexe non, c'est même d'une logique assez simple que de créer des tas et des tas de nouvelles micro-classes et interfaces fonctionnelles génériques destinés a des usages bien précis et spécifiques comme le faisait la STL de C++ déjà, bien avant que Java ne s'y mette. Ça n'en reste pas moins illisible pour autant. Or un code illisible n'est pas aisément maintenable, encore plus lorsqu'on le confie a des débutants.
    C'est là ou parfois la "logique de construction" du code, puis des méthodes et enfin des classes (pour prendre une approche bottom-up comme dans le cadre d'une refactorisation) aide réellement. Après on discute un peu dans le vide mais je soulignais juste l'idée que si on fait parfois du code brouillon, il suffit de le mettre au propre pour que tout s'illumine.
    Un autre point, la lisibilité d'un écrit tient parfois uniquement à l'expérience dans la "construction". Ainsi je pense qu'un code LISP/OCamel/Haskell peut être compliqué à lire au premier abord mais qu'avec l'expérience, il devient évident.

    Dans cet ordre d'idée, je me souviens avoir galéré au premier abord à obtenir des résultats avec Prolog ou R. Mais avec un peu de pratique c'est devenu évident et puissant. J'ai remarqué que d'autres avaient le même soucis lors de l'apprentissage du SQL.
    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

  15. #75
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 547
    Points : 21 602
    Points
    21 602
    Par défaut
    Citation Envoyé par Nemek Voir le message
    Et qui dit que la valeur "null" doit être acceptable pour un primitif ?
    Ben la même personne qui a voulu que les types primitifs soient aussi objet. En Java soit on a pas de valeur null, soit on est un type objet, on choisit l'un ou l'autre.
    En poussant un peu on pourrait à la rigueur considérer qu'au runtime un type primitif n'a pas le droit de se faire assigner null, tout comme un Object[0] n'a pas le droit de se faire assigner un Integer si le type réel du tableau est Date[]. Mais dans ce cas ça a pas servi à grand-chose, et il faut faire ces vérifications à chaque assignation où la question se pose, d'où perte de performances.

    L'intérêt d'être type objet c'est pas de pouvoir se bercer de pensées rassurantes "bon, cette fois je ne manipule que des objets, tout va bien." Dans un langage statiquement typé, l'intérêt d'être type objet c'est que le type est hiérarchisé et peut intervenir dans un code générique au lieu de spécialiste*.
    Au moins donc dans la portée de tel code générique, le type primitif doit pouvoir accepter la valeur null, ou au moins l'idée que cette valeur existe ce qui revient au même. Les Wrappers tels qu'ils fonctionnent à présent s'en occupant d'ailleurs très bien, générant des NullPointerException à l'auto-outbox. Au prix d'une large perte de performances.

    * On pourrait me rétorquer qu'on pourrait générifier du comportement sur des types primitifs, des choses comme le + ou le max étant applicables à tous les primitifs numériques, qui pourtant ne peuvent pas prendre la valeur null. Ok, et je reconnais que ce serait bougrement utile. mais là on parle pas de les rendre objet, on parle de leur définir un supertype à eux seuls, qui gère les + et max et ce genre de choses, bref fonctionne comme eux et n'est pas de type objet.

    Citation Envoyé par Nemek Voir le message
    Au pire ca ne fait qu'un état (et de la mémoire) supplémentaire à gérer.
    Cet état ne s'est pas généré tout seul et ne sert à rien si on ne va jamais regarder ce qui s'y trouve et qu'on utilise seulement ce qu'on avait avant qu'il existe.
    Perte de performances donc. Pour l'initialiser, et quand on est bien obligé d'aller le vérifier, raison pour laquelle il existe.

    À la rigueur si on change vraiment beaucoup les règles du langage Java, ça ne sera pas très lourd en perte de performances, certes. Mais là en termes de changements c'est pas de la rigolade. Génériques, lambdas ? De la gnognotte.

    Citation Envoyé par Nemek Voir le message
    Les deux exemples étaient juste pour souligner que rien ne motive réellement le choix de ne pas permettre la définition d'opérateur sur d'autres type et notemment BigInteger.
    Si : pour la cohérence du langage, ce n'était possible que pour deux cas exceptionnels : primitifs et String, la liste complète étant concise et connue.
    ... Après je dis pas que je suis fondamentalement opposé à permettre la définition d'opérateurs dans les types objets, mais la simplicité du langage qu'on retirait en ne le permettant pas, est évidente.

    Citation Envoyé par Nemek Voir le message
    J'avoue que c'est pas clean. Mais rien n'empêche d'initialiser tout à 0, puis d'invoquer le constructeur des "valeurs".
    Ouais enfin il faut tout de même aller le chercher, maintenant, ce constructeur, c'est quand même pas rien. Ça change beaucoup de choses aux règles du format de classe et d'allocation d'objet. Et je ne parle pas des outils qui comptaient sur le fait que l'allocation se fasse en O(n), n étant la taille mémoire des champs d'instance et donc typiquement bas et en réalité O(1). Bref en plus clair passer d'une opération atomique du point de vue du thread à une opération non atomique, c'est rude.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  16. #76
    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 : 38
    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 083
    Points
    7 083
    Par défaut
    Mea Culpa pour l'initialisation des "value" c'était une fausse bonne idée. Au delà des arguments mentionnés, il y a des cas vraiment trop complexes. Et comme je le disais l'initialisation à vide ne devrait pas poser de problèmes ou alors pas plus que maintenant avec les types primitifs et les objets.

    Reste donc encore le problème de la nullité ; même si celui-ci a été délégué à une autre étude. De manière générale, je préfère l'approche prise par certains langages (ex: Ceylon) de ne pas considérer "null" comme une valeur universelle (acceptable pour tous les types). Celle-ci devrait être réservé à un type Nullable.
    De ce que j'ai pu y penser, il faudrait faire disparaître les wrappers de l'API. En interne, tant qu'on manipule un type précis (non générique), on garde le fonctionnement actuel et la valeur ne peut jamais être null. Autrement, il faut nécessairement "marquer" la nullité :
    1. Le plus simple (et le fonctionnement actuel) c'est d'utiliser un "wrapper" mais ceci serait invisible pour le programmeur ;
    2. Deuxième option un peu plus complexe, stocker l'état avec la valeur. Ceci pose le problème de la taille allouée pour gérer normalement une référence. Par exemple si j'ai une classe avec uniquement cet attribut private T element;, pour le moment je sais qu'il me faut un nombre fixe de bit que la taille de l'architecture (32 ou 64 bits). Là, il faudrait allouer au moins un octet (voir 4 ou 8) de plus.
    3. Dernière option plus complexe, alloué les primitifs/valeurs par paquet et utiliser un "BitSet" pour marquer la nullité.

    Pour les deux dernières solutions, il est nécessaire de supprimer la co/contra-variance pour les génériques portant sur des types primitifs/valeurs. Ainsi List<?> liste = new ArrayList<int>(); ou List<long> liste = new ArrayList<int>(); seraient interdits.

    Une autre alternative peut-être plus simple que tout cela. Introduire explicitement une hiérarchie alternative à java.lang.Object : java.lang.Value. Ce serait la "classe" parente des types primitifs et value type. Value ne serait pas "nullable". Concernant les génériques deux options :
    1. Soit il existe un parent commun (ex : java.lang.Data), les génériques s'appliquent par défaut à java.lang.Object et les instances peut-être nullables. Mais on peut également indiqué qu'on utilise indifféremment une valeur ou une référence en faisait T extends Data ou bien un(e) primitif/valeur quelconque T extends Value, mais dans ce cas "null" n'est pas acceptable. Reste à savoir si l'on admet un nouveau mot clé qui pourrait exprimer une "valeur neutre" (ex : "default") : null pour les références, 0 pour les nombres, false pour les booléens, ??? pour les autres valeurs.
    2. Un générique doit nécessairement s'appliquer soit à une valeur, soit à une référence. Auquel cas, null existe dans un cas mais pas dans l'autre. Mais la question du "default" risque de se poser tout de même. Et cela nécessite au moins de dupliquer toutes les classes génériques (une version pour les références et une autre pour les primitifs/valeurs. Mais au moins la version pour les valeurs est valable pour tous les primitifs/valeurs.

    Bien entendu la restriction de la variances des génériques est maintenue.


    Qu'en pensez-vous ?
    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

  17. #77
    Nouveau Candidat au Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2014
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2014
    Messages : 1
    Points : 1
    Points
    1
    Par défaut Analyse numérique...
    Je vois dans cette initiative un intérêt énorme en rapport avec l'analyse numérique et plus particulièrement le calcul intensif, domaine dans lequel Java pourrait avoir d'énormes points forts (parallélisme, calcul distribué, code optimisé des boucles). Ce domaine a été totalement négligé jusqu'ici, au grand dam de la communauté scientifique qui pourtant avait lancé pas mal d'initiatives pour faire bouger les concepteurs de Java (cf position de James Gosling par rapport à l'implémentation des doubles : http://www.cs.berkeley.edu/~wkahan/JAVAhurt.pdf ).
    Ce mécanisme permettrait l'introduction de types réels bien meilleurs que ceux disponibles pour le moment (précision, détection de dépassement de capacité) ainsi que de types complexes comme les matrices. Il faudrait ajouter encore à cela la surcharge (très encadrée) des opérateurs pour ces types afin de rendre le code scientifique lisible.
    On va dans le bon sens.

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, 11h20
  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, 16h55
  3. Réponses: 1
    Dernier message: 02/04/2009, 18h36
  4. Réponses: 4
    Dernier message: 23/03/2009, 12h20

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