L'inferenza di Hindley-Milner può funzionare per la lingua Go?

22

Ho letto che Hindley-Milner non funziona con i sistemi di tipi che hanno sottoclassi e ci sono altre funzionalità di sistema di tipo che anche non funzionano bene con esso. Vai attualmente ha inferenza di tipo molto limitata nell'operatore := . Ma Go non ha sottoclassi nel senso tradizionale, solo interfacce che assomigliano molto alle classi tipo di Haskell che funzionano bene con l'inferenza di Hindley-Milner.

Quindi, l'inferenza di Hindley-Milner potrebbe funzionare in linea di principio per Go allo stesso modo di Haskell? O Go ha altre caratteristiche che lo infrangono? (D'altra parte, Haskell ha anche alcune caratteristiche che non funzionano con Hindly-Milner, se usi quelle devi digitare manualmente quelle parti del tuo programma.)

    
posta JanKanis 18.04.2016 - 14:44
fonte

1 risposta

35

L'inferenza di tipo Hindley-Milner viene utilizzata per i sistemi di tipo Hindley-Milner, una restrizione dei sistemi di tipo System-F. La caratteristica interessante dei sistemi di tipo HM è che hanno polimorfismo parametrico (ovvero generici). Questa è la caratteristica del sistema di caratteri più grande che Golang si rifiuta di avere.

Con questa restrizione frustrante, l'inferenza di tipo stile HM è impossibile. Diamo un'occhiata al codice non tipizzato:

func f(a) {
  return a.method()
}

Qual è il tipo di f ? Potremmo notare che a deve avere un metodo, quindi potremmo usare un'interfaccia anonima: func f(a interface { method() ??? }) ??? . Tuttavia, non abbiamo idea di cosa sia il tipo di ritorno. Con le variabili di tipo, potremmo dichiarare il tipo come

func f[T](a interface{ method() T }) T

Tuttavia, Go non ha variabili di tipo quindi non funzionerà. Mentre le interfacce implicite semplificano alcuni aspetti dell'inferenza di tipo, ora non abbiamo modo di scoprire il tipo di ritorno di una chiamata di funzione. Il sistema HM richiede che tutte le funzioni siano dichiarate piuttosto che implicite e ogni nome può avere un solo tipo (mentre i metodi di Go possono avere tipi diversi in interfacce diverse).

Invece, Go richiede che le funzioni siano sempre dichiarate completamente, ma consente alle variabili di utilizzare l'inferenza di tipo. Questo è possibile perché il lato destro di un compito variable := expression ha già un tipo noto in quel punto del programma. Questo tipo di inferenza di tipo è semplice, corretta e lineare.

  • Il tipo di una variabile è immediatamente noto al punto della dichiarazione, mentre l'inferenza HM deve potenzialmente controllare prima l'intero programma. Ciò ha anche un notevole impatto sulla qualità dei messaggi di errore.
  • L'approccio di inferenza del tipo di Go selezionerà sempre il tipo più specifico per una variabile, al contrario di HM che seleziona il tipo più generale. Questo funziona in modo pulito con sottotipizzazione, anche con le interfacce implicite di Go.
risposta data 18.04.2016 - 15:18
fonte

Leggi altre domande sui tag