[théorie] généricité: quelques soucis
(bon Wichtounet m'a dit qu'il n'y avait aucun mal à poster des choses théoriques et abstraites donc voici un petit brainstorming -dans ce qui suit remplacer toutes les affirmations par "il me semble que" ;) -).
J'ai des soucis avec la généricité: le compilateur appliquant la règle "dans le doute abstiens toi" je me retrouve de temps en temps dans des impasses. Je n'ai rien contre les compilateurs pessimistes mais quand même.
Voici un exemple:
Code:
1 2 3 4 5 6 7
|
class Truc implements Trucable{
.....
}
Iterator<Truc> iterT ; .....
Iterator<Trucable> iter = iterT; // compile pas : principe d'invariance
Iterator<? extends Trucable> iter = iterT ; // OK |
Bien .... sauf que c'est pas toujours possible d'avoir la dernière instruction (par exemple dans une classe qui fait "implements Iterable<Trucable>" bon je détaille pas ici pourquoi on ne peut pas toujours se trouver dans la config favorable).
Le triste de l'histoire c'est que dans ce cas le contrôle de type se trouve vérifié (mais que le compilateur ne l'entend pas de cette oreille). En effet le résultat du next() si il est de type Truc est affectable à un Trucable!
Certains ont proposé que la définition d'Iterable<X> soit de définir une méthode iterator() qui rende un <? extends X> mais ça ne résout pas tout.
Quelques principes que je soumet à votre sagacité:
- si une interface paramétrée en X ParmInterf<X> n'utilise X que pour les résultats de ses méthodes alors:
* on peut affecter un ParmInterf<Truc> à un ParmInterf<Trucable> (le principe d'invariance ne s'applique pas).
* si le paramètre X est remplacé par un type paramétré c'est plus compliqué
Code:
1 2 3 4
|
ParmInterf<Iterable<Trucable>> <- ParmInterf<Iterable<Truc>> // OK
ParmInterf<List<Trucable>> <- ParmInterf<ArrayList<Trucable>> //OK
ParmInterf<List<Trucable>> <- ParmInterf<List<Truc>> // NON! invariance |
en supposant que des propriétés de ce genre soit justes (ce qui n'est pas prouvé) quelles conclusions en tirer?
Que se passerait-il si on adoptait un compilateur moins dépressif qui marque le code de ParmInterf pour vérifier ensuite des règles sophistiquées d'utilisation?
Eh bien les codes génériques qui sont déjà passablement obscurs deviendraient totalement illisibles pour le commun des mortels!
<brainstorming> ... et si il avait alors un dispositif syntaxique (appelons ça une clause d'indulgence) qui permette au programmeur d'indiquer qu'il demande l'application de règles plus sophistiquées?
d'abord ça permettrait de régler quelques autres situations embarassantes (j'en ai d'autres exemples :cry: ) ensuite c'est déjà pas totalement absent de Java .... exemple:
Code:
1 2 3 4
|
List<Truc> liste = new ArrayList<Truc>() ;
List<Trucable> lst = Collections.unmodifiableList(liste );// SE COMPILE PAS
List<Trucable> lst = Collections.<Trucable>unmodifiableList(liste ); // OK!! |
des idées? des réactions (peut-être suis je complètement en dehors des clous et il faudrait que je fasse réviser mon neurone)?
merci de votre attention.