A inferência do tipo Hindley-Milner é usada para sistemas do tipo Hindley-Milner, uma restrição dos sistemas do tipo System-F. A característica interessante dos sistemas do tipo HM é que eles têm polimorfismo paramétrico (também conhecido como genéricos). Esse é o maior recurso do sistema de tipos que a Golang se recusa a ter.
Com essa restrição frustrante, a inferência do tipo HM é impossível. Vamos dar uma olhada no código não digitado:
func f(a) {
return a.method()
}
Qual é o tipo de f
? Podemos perceber que a
deve ter um método, para que pudéssemos usar uma interface anônimo: func f(a interface { method() ??? }) ???
. No entanto, não temos idéia de qual é o tipo de retorno. Com variáveis de tipo, poderíamos declarar o tipo como
func f[T](a interface{ method() T }) T
No entanto, o Go não possui variáveis de tipo, portanto isso não funcionará. Embora as interfaces implícitas facilitem alguns aspectos da inferência de tipos, agora não temos como descobrir o tipo de retorno de uma chamada de função. O sistema HM requer que todas as funções sejam declaradas, e não implícitas, e cada nome pode ter apenas um único tipo (enquanto os métodos de Go podem ter tipos diferentes em diferentes interfaces).
Em vez disso, o Go requer que as funções sejam sempre totalmente declaradas, mas permite que as variáveis usem inferência de tipo. Isso é possível porque o lado direito de uma atribuição variable := expression
já possui um tipo conhecido naquele ponto do programa. Esse tipo de inferência de tipo é simples, correto e linear.
- O tipo de uma variável é imediatamente conhecido no ponto da declaração, enquanto a inferência do HM deve verificar o tipo potencialmente todo o programa primeiro. Isso também tem um impacto perceptível na qualidade das mensagens de erro.
- A abordagem de inferência de tipo da Go sempre seleciona o tipo mais específico para uma variável, em contraste com o HM, que escolhe o tipo mais geral. Isso funciona perfeitamente com a subtipagem, mesmo com as interfaces implícitas do Go.