En programmation, la généricité (ou programmation générique) consiste à définir des algorithmes identiques opérant sur des données de types différents. On définit de cette façon des procédures ou des types entiers génériques. On pourrait ainsi programmer une pile, ou une procédure qui prend l'élément supérieur de la pile, indépendamment du type de données contenues.
C'est donc une forme de polymorphisme, le « polymorphisme de type » dit aussi « paramétrage de type » : en effet, le type de donnée général (abstrait) apparaît comme un paramètre des algorithmes définis, avec la particularité que ce paramètre-là est un type. C'est un concept important pour un langage de haut niveau, car il permet d'écrire des algorithmes généraux opérant sur toute une série de types : la généricité augmente donc le niveau d'abstraction des programmes écrits dans un langage qui possède cette fonctionnalité. Divers mécanismes ont été conçus pour permettre la programmation générique.
Ian Lance Taylor a expliqué sur la page dédiée à Go :
« Nous avons déposé une proposition de changement de langage Go pour ajouter la prise en charge des paramètres de type pour les types et les fonctions, permettant une forme de programmation générique.
« Les génériques peuvent nous donner des blocs de construction puissants qui nous permettent de partager du code et de créer des programmes plus facilement. La programmation générique signifie écrire des fonctions et des structures de données où certains types doivent être spécifiés ultérieurement. Par exemple, vous pouvez écrire une fonction qui opère sur une tranche d'un type de données arbitraire, où le type de données réel n'est spécifié que lorsque la fonction est appelée. Vous pouvez également définir une structure de données qui stocke des valeurs de tout type, où le type réel à stocker est spécifié lorsque vous créez une instance de la structure de données.
« Depuis la sortie de Go pour la première fois en 2009, la prise en charge des génériques est l'une des fonctionnalités du langage les plus demandées.
« Bien que les génériques aient des cas d'utilisation clairs, les adapter proprement dans un langage comme Go est une tâche difficile. L'une des premières tentatives (erronées) d'ajouter des génériques à Go remonte à 2010. Il y en a eu plusieurs autres au cours de la dernière décennie.
« Depuis quelques années, nous travaillons sur une série de projets de conception qui ont abouti à une conception basée sur des paramètres de type. Ce projet de conception a reçu beaucoup de commentaires de la communauté de programmation Go, et de nombreuses personnes l'ont expérimenté en utilisant le terrain de jeu générique décrit dans un billet de blog précédent. Ian Lance Taylor a donné un discours à la GopherCon 2019 sur les raisons d'ajouter des génériques et la stratégie que nous suivons maintenant. Robert Griesemer a donné un discours de suivi sur les changements dans la conception et la mise en œuvre à GopherCon 2020. Les changements de langage sont entièrement rétrocompatibles, de sorte que les programmes Go existants continueront à fonctionner exactement comme ils le font aujourd'hui. Nous avons atteint le point où nous pensons que le projet de conception est assez bon et assez simple pour proposer de l'ajouter à Go ».
Les génériques peuvent fournir des blocs de construction puissants pour partager du code et créer plus facilement des programmes. Avec la programmation générique, l'écriture de fonctions et de structures de données peut être effectuée d'une manière où certains types sont spécifiés par la suite. Par exemple, un développeur pourrait écrire une fonction qui opère sur une tranche d'un type de données arbitraire, où le type de données réel est spécifié lorsque la fonction est appelée. Un développeur pourrait également définir une structure de données qui stocke des valeurs de tout type, dans laquelle le type réel à stocker est spécifié lorsqu'une instance de la structure de données est créée.
Les changements de haut niveau dans la proposition de programmation générique pour Go comprennent ceci :
- Les fonctions peuvent avoir une liste de paramètres de type supplémentaire qui utilise des crochets, mais qui autrement ressemble à une liste de paramètres ordinaire: func F [T any] (p T) {...}
- Ces paramètres de type peuvent être utilisés par les paramètres réguliers et dans le corps de la fonction.
- Les types peuvent également avoir une liste de paramètres de type: type MySlice [T any] [] T
- Chaque paramètre de type a une contrainte de type, tout comme chaque paramètre ordinaire a un type : func F [T Constraint] (p T) {...}
- Les contraintes de type sont des types d'interface.
- Le nouveau nom prédéclaré any est une contrainte de type qui autorise n'importe quel type.
- Les types d'interface utilisés comme contraintes de type peuvent avoir une liste de types prédéclarés; seuls les arguments de type qui correspondent à l'un de ces types satisfont à la contrainte.
- Les fonctions génériques ne peuvent utiliser que les opérations autorisées par leurs contraintes de type.
- L'utilisation d'une fonction ou d'un type générique nécessite de passer des arguments de type.
- L'inférence de type permet d'omettre les arguments de type d'un appel de fonction dans les cas courants.
Adapter les génériques à un langage tel que Go est une tâche difficile, comme l'indiquent des tentatives infructueuses datant de 2010. Au cours des deux dernières années, les développeurs de Go ont travaillé sur une série de projets de conception qui ont abouti à une conception basée sur des paramètres de type. Le projet a reçu la contribution de la communauté de programmation Go, et il y a eu quelques expériences avec lui via le terrain de jeu des génériques. Les changements de langage prévus pour la prise en charge des génériques sont rétrocompatibles, de sorte que les programmes Go existants continueraient à fonctionner.
« Le processus de proposition de changement dans le langage est la façon dont nous apportons des modifications au langage Go. Nous avons maintenant commencé ce processus pour ajouter des génériques à une future version de Go. Nous invitons les critiques et les commentaires de fond, mais essayez d'éviter de répéter les commentaires précédents et essayez d'éviter les simples commentaires plus un et moins un. Au lieu de cela, ajoutez des réactions emoji « pouce vers le haut / pouce vers le bas » aux commentaires avec lesquels vous êtes d'accord ou en désaccord, ou à la proposition dans son ensemble.
« Comme pour toutes les propositions de changement dans le langage, notre objectif est de parvenir à un consensus pour soit ajouter des génériques au langage, soit laisser tomber la proposition. Nous comprenons que pour un changement de cette ampleur, il sera impossible de rendre tout le monde heureux dans la communauté de Go, mais nous avons l'intention de prendre une décision que tout le monde est prêt à accepter.
« Si la proposition est acceptée, notre objectif sera d'avoir une implémentation complète, mais peut-être pas entièrement optimisée, que les gens pourront essayer d'ici la fin de l'année, peut-être dans le cadre des bêtas Go 1.18 ».
Source : billet de blog Go
Et vous ?
Utilisez-vous Go ? Si oui, qu'en pensez-vous ?
Que pensez-vous de la programmation générique dans l'absolu ?
Êtes-vous pour ou contre une forme de programmation générique dans Go ?