• [^] # Re: Inférence de types

    Posté par (site web personnel) . En réponse à la dépêche Sortie de JDK 10. Évalué à 10.

    Suffit de passer ce "var" magique à une API qui a des méthodes de même nom mais avec des arguments de types différents pour être sûr d'avoir du code Java du niveau d'un code javascript...

    Je ne vois pas le rapport. Le problème de JavaScript ou de Python à ce niveau c'est que tu peux avoir une variable de type entier qui est passé à une fonction où le type attendu est une chaîne de caractères ou inversement.

    Là tu parles d'un cas où l'inférence de type a retrouvé le type tout seul et a pu appeler une méthode qui est du bon type. Du coup il n'y a pas de comportement bizarres à prévoir. D'autant plus que le compilateur ne fait pas des divinations très poussées, cela reste souvent assez élémentaire.

    Quand tu écris :

    auto entier = 0;
    auto booleen = false;
    auto chaine = "chaîne de caractère";
    auto classe_complexe = copie_de_cette_classe;
    auto autre_classe_complexe = AutreClasseComplexe(entier, booleen);

    Tu crois qu'il va comprendre quoi ? Ce sera évident le type résultant. Et c'est 90% des cas où l'inférence de type sera utilisé. Le compilateur ne va clairement pas se vautrer sur ça. Car quand ce n'est pas assez clair ce qu'il doit faire, il va râler.

    Je ne parle même pas des problèmes de refactoring que cela implique.

    Grâce au typage fort et à la simplicité de l'écriture, cela fonctionne mieux que sans. Testé et approuvé.

    L'argument C++ et autre, je vois pas le rapport, en C++ on peut aussi se contenter de void** !

    J'ai dis C++ moderne (donc C++11, 14 ou 17). Le C++ à la C avec des pointeurs nus et des casts implicites et compagnie cela ne se fait plus dans les projets modernes (ou ne devraient pas se faire). Bientôt tu vas me parler de Java 1 aussi ?

    Note que Rust et OCaml sont eux irréprochables en terme d'inférence de type et de typage fort. Des langages de conception modernes n'ayant aucun historique à porter là dessus.

    Tu m'explique comment tu arrives à mieux lire le type de toto pour savoir quoi en faire 3 lignes plus bas?

    L'inférence de type est un outil, si tu trouves qu'à un moment c'est plus lisible d'être explicite, fais-le. Cela ne signifie pas que la fonctionnalité est mauvaise pour autant.

    on parle de type, pas de nom de variable ou de paramètre, gagner quelques octets dans un code source n'apporte rien à moins d'avoir de sérieuses douleurs au doigts.

    Je ne parle pas de gagner en temps de frappe, quoique. Mais un code peut avoir des types à rallonge. Du coup tu perds en lisibilité car ton code sera dense qui va noyer ce qui est réellement important.

    L'exemple le plus connu est sans doute les itérateurs en C++. Je préfère mille fois lire ça :

    for (auto it = conteneur.cbegin(); it != conteneur.cend(); it++)
     // Utiliser l'itérateur

    Ou mieux encore :

    for (auto element : conteneur)
     // Utiliser l'élément

    Que :

    for (std::vector<UneClassePerso>::const_iterator it = conteneur.cbegin(); it != conteneur.cend(); it++)
     // Utiliser l'itérateur

    Car oui tu peux rapidement avoir des noms complexes du genre, et je te passe le cas quand c'est un tuple, une map ou autre qui peuvent grossir la taille de la déclaration.

    Si tu fais des fonctions courtes, que tes variables et méthodes sont bien nommées (bref, respecter les bonnes pratiques) tu es largement gagnant à utiliser l'inférence de type. C'est comme râler sur les templates, lambda, etc. en pointant sur un cas de mauvaise utilisation. Alors que pourtant ils sont utiles aussi. C'est comme tout, faut pas en abuser mais on n'a aps à s'en priver.