J'ai choisi de fournir une surcharge ordinaire et des classes de types multi-types dans mon langage Felix.
Je considère que la surcharge (ouverte) est essentielle, en particulier dans un langage qui a beaucoup de types numériques (Felix a tous les types numériques de C). Cependant, contrairement à C ++ qui abuse de la surcharge en faisant dépendre les modèles, le polymorphisme Felix est paramétrique: vous avez besoin d'une surcharge pour les modèles en C ++ car les modèles en C ++ sont mal conçus.
Les classes de type sont également fournies dans Felix. Pour ceux qui connaissent le C ++ mais qui ne plaisantent pas avec Haskell, ignorez ceux qui le décrivent comme une surcharge. Ce n'est pas comme une surcharge à distance, c'est plutôt comme une spécialisation de modèle: vous déclarez un modèle que vous n'implémentez pas, puis fournissez des implémentations pour des cas particuliers selon vos besoins. Le typage est paramétriquement polymorphe, l'implémentation se fait par instanciation ad hoc mais elle n'est pas destinée à être sans contrainte: elle doit implémenter la sémantique voulue.
Dans Haskell (et C ++), vous ne pouvez pas énoncer la sémantique. En C ++, l'idée "Concepts" est à peu près une tentative d'approximation de la sémantique. Dans Felix, vous pouvez approximer l'intention avec des axiomes, des réductions, des lemmes et des théorèmes.
Le principal, et seulement avantage de la surcharge (ouverte) dans un langage bien fondé sur des principes comme Felix est qu'il facilite la mémorisation des noms de fonction de bibliothèque, à la fois pour l'auteur du programme et pour le réviseur de code.
Le principal inconvénient de la surcharge est l'algorithme complexe requis pour l'implémenter. Cela ne correspond pas non plus très bien à l'inférence de type: bien que les deux ne soient pas entièrement exclusifs, l'algorithme pour faire les deux est suffisamment complexe, le programmeur ne serait probablement pas en mesure de prédire les résultats.
En C ++, c'est aussi un problème car il a un algorithme de correspondance bâclé et prend également en charge les conversions de type automatiques: dans Felix, j'ai "corrigé" ce problème en exigeant une correspondance exacte et aucune conversion de type automatique.
Vous avez donc un choix, je pense: surcharge ou inférence de type. L'inférence est mignonne, mais elle est également très difficile à mettre en œuvre d'une manière qui diagnostique correctement les conflits. Ocaml, par exemple, vous indique d'où il détecte un conflit, mais pas d'où il a déduit le type attendu.
La surcharge n'est pas beaucoup mieux, même si vous avez un compilateur de qualité qui essaie de vous dire tous les candidats, il peut être difficile de lire si les candidats sont polymorphes, et pire encore s'il s'agit de piratage de modèles C ++.