Des raisons d’utiliser l’inférence de type
L’utilisation de l’inférence de type sur les variables locales en Java peut-être source de débat sur son bien-fondé au sein des pratiquant(e)s. Cet article ne se veut objectif, une des réponses les plus pertinentes sur Reddit.com à la question “Is using var okay?” étant :
Let’s have a 4 hour company wide meeting to discuss this.
Histoire
En 2016 Brian Goetz propose via la JEP 286 (Java Enhancement Proposal) l’introduction d’un nouveau mot dans le standard, qui permet l’inférence de type de lors de la déclaration-initialisation de variables locales, comme on le trouve dans certains langages (auto
en C++, var
/let
/const
en Javascript). L’objectif est alors d’alléger l’écriture tout en conservant le typage statique du langage.
Il propose également plusieurs choix de syntaxe, parmi lesquels (liste non exhaustive):
const x = expr
final x = expr
let x = expr
def x = expr
x := expr
Un sondage est alors réalisé parmi les développeurs Java pour récolter les avis sur la pertinence d’une telle fonctionnalité, ansi que sur la préférence syntaxique. Il en ressort des résultats résumés dans cette communication que 74% des personnes interrogées se déclarent favorables à son introduction, 12% moyennement convaincues et 10% contre avec comme principal argument la réduction de la lisibilité.
La proposition sera adoptée et incluse dans Java 10, publié en mars 2018.
Raison n°1 : on écrit moins, on lit moins, on se porte mieux…
- moins verbeux et plus rapide à écrire ex: template ex: stream ?
BiFunction<Double, Double, Double> hypot = (x, y) -> Math.sqrt(x*x + y*y);
double x = 9.0;
double y = 12.0;
double h = hypot(x, y);
BiFunction<Double, Double, Double> hypot = (x, y) -> Math.sqrt(x*x + y*y);
double x = 9.0;
double y = 12.0;
double h = hypot(x, y);
Raison n°2 : …et de toute façon on ne lit pas vraiment…
Un des arguments principal contre le var c’est “on ne sait pas ce qu’on manipule”. Lors d’une assignation (et encore plus lors d’une déclaration-assignation), ce qui nous intéresse en premier c’est l’opérande de droite. Ce qu’on retient de la ligne c’est ça prend la valeur de quelqu
- lecture de droite à gauche
-microsoft C# Use var only when a reader can infer the type from the expression. Readers view our samples on the docs platform. They don’t have hover or tool tips that display the type of variables. https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions - google ?
Raison n°3 : …parce que la vérité est ailleurs.
Les critères de lisibilité d’un code sont vaste, enclins à de nombreuses discussions, la recherche scientifique dispose d’ailleurs de papiers sur le sujet, et on ne cherchera pas à les définir ici. Dans tous les cas, la lisibilité du code ne dépend certainement pas uniquement de l’utilisation de telle ou telle fonctionnalité d’un langage. La responsabilité d’écrire un code lisible appartient au développeur plus qu’au langage. Un des fondamentaux de ce métier est de savoir définir des types et des structures de données qui apportent d’eux-même une sémantique à l’écriture. C’est la définition de ces types qui permet de comprendre la nature des objets que l’on manipule, leur propriètes et parfois même une partie de leur fonctionnement, et c’est donc bien par une bonne définition des types que tout doit passer.
En exemple, on voit de plus en plus souvent en Python notamment l’utilisation de dictionnaires (équivalent des HashMap<>
en Java) pour stocker toute sorte d’objet. Bien qu’ils soient aisément manipulables et qu’ils présentent une bonne performance générale, il s’agit là probablement d’une facilité qui tend plus à obscurcir un code qu’à en enrichir sa compréhension immédiate. Retour en Java avec un exemple de 2 classes qui permettent de stocker un objet lu à partir d’un JSON:
Avec un type bien défini, les propriètes sont visibles dès le départ,
// Définition
record Article(Integer id, Float price, String name) {}
// Utilisation
var article = new Article();
// Manipulation classique via les accesseurs...
int id = article.getId();
article.setPrice(12.50f);
Sans type, la définition n’a pas d’existence propre, et peut évoluer (ou dégénérer) au fil du code.
// Pas de définition de type particulier, on se base sur HashMap<String, Object>
// Utilisation
var article = new HashMap<String, Object>();
article.put("id", 14);
article.put("price", 12.50f);
article.get("name ",count);
L’utilisation de var
n’est donc pas déterminante dans la charge cognitive allouée à la lecture.