L'inférence de type Hindley-Milner est utilisée pour les systèmes de type Hindley-Milner, une restriction des systèmes de type System-F. La caractéristique intéressante des systèmes de type HM est qu'ils ont un polymorphisme paramétrique (alias génériques). C'est la plus grande fonctionnalité de système de type que Golang refuse d'avoir.
Avec cette restriction frustrante, l'inférence de type HM est impossible. Regardons le code non typé:
func f(a) {
return a.method()
}
Quel est le type de f
? On peut remarquer que a
doit avoir une méthode, afin que nous puissions utiliser une interface anonyme: func f(a interface { method() ??? }) ???
. Cependant, nous n'avons aucune idée du type de retour. Avec les variables de type, nous pourrions déclarer le type comme
func f[T](a interface{ method() T }) T
Cependant, Go n'a pas de variables de type, donc cela ne fonctionnera pas. Alors que les interfaces implicites facilitent certains aspects de l'inférence de type, nous n'avons désormais aucun moyen de trouver le type de retour d'un appel de fonction. Le système HM exige que toutes les fonctions soient déclarées plutôt qu'impliquées, et chaque nom ne peut avoir qu'un seul type (alors que les méthodes de Go peuvent avoir différents types dans différentes interfaces).
Au lieu de cela, Go requiert que les fonctions soient toujours entièrement déclarées, mais autorise les variables à utiliser l'inférence de type. Cela est possible car le côté droit d'une affectation a variable := expression
déjà un type connu à ce point du programme. Ce type d'inférence de type est simple, correct et linéaire.
- Le type d'une variable est immédiatement connu au moment de la déclaration, tandis que l'inférence HM doit potentiellement d'abord vérifier le type de tout le programme. Cela a également un impact notable sur la qualité des messages d'erreur.
- L'approche d'inférence de type de Go sélectionnera toujours le type le plus spécifique pour une variable, contrairement à HM qui choisit le type le plus général. Cela fonctionne proprement avec le sous-typage, même avec les interfaces implicites de Go.