Digitare l'inferenza per le istruzioni imperative diverse dall'assegnazione


10

Nella mia ricerca di articoli di ricerca sui sistemi di tipi per le lingue imperative, trovo solo soluzioni per una lingua con riferimenti mutabili ma senza strutture di controllo imperative autentiche come operatori composti, loop o condizionali.

Quindi non è chiaro come implementare un linguaggio imperativo con inferenza di tipo parziale come http://rust-lang.org .

I documenti non menzionano tipi parametrici come List of aperché i tipi parametrizzati sono una banale estensione del sistema di tipi Hindley-Milner - solo l'algoritmo di unificazione dovrebbe essere esteso e il resto dell'inferenza funziona così com'è. Tuttavia, le assegnazioni non possono essere aggiunte banalmente perché sorgono paradossi, quindi devono essere applicate tecniche speciali come la limitazione del valore ML.

Puoi consigliare documenti o libri che descrivono un sistema di tipi per un linguaggio con loop imperativi, condizionali, IO e dichiarazioni composte?


4
Non sono sicuro di aver capito l'origine della tua domanda, in parte perché Standard ML in realtà ha operatori composti, loop e condizionali (esempio di una riga:) let val x = ref 9 in while !x>0 do (print (Int.toString (!x)); x := !x-1) end. Quindi a livello di una domanda di ricerca, è la risposta che stai cercando "applica tecniche sviluppate in Caml / SML, inclusa la restrizione del valore"?
Rob Simmons,

La domanda era "quali articoli sulle tecniche sviluppate per Caml / SML mi consigliate?"
nponeccop,

Ok - L'avevo capito e stavo per provare a modificare la mia ultima frase per dire "È quello che stai cercando un riferimento accessibile per l'inferenza di tipo Hindley-Milner come viene usato in ML?" E poi ho raggiunto il limite di modifica di 5 minuti :-)
Rob Simmons,

Risposte:


14

Se stai cercando un riferimento pulito e funzionale all'inferenza di tipo, sono un po 'parziale rispetto a " Inferenza del tipo nel contesto " di Gundry, McBride e McKinna del 2010 , anche se questo potrebbe non essere una buona guida per le attuali implementazioni esistenti .

Penso che parte della risposta sia che, al di là della limitazione del valore, non c'è davvero molta difficoltà ad adattare l'inferenza di tipo Hindley-Milner ai linguaggi imperativi: se si definisce e1; e2come zucchero sintattico (fn _ => e2) e1e si definisce while e1 do e2come zucchero sintattico per whiledo e1 (fn () => e2), dove whiledoc'è un regolare funzione ricorsiva

fun whiledo g f = if g then (f (); whiledo g f) else ();

allora tutto funzionerà bene, inclusa l' inferenza del tipo.

Per quanto riguarda la limitazione del valore essendo una tecnica speciale, mi piace la seguente storia; Sono abbastanza sicuro di averlo raccolto da Karl Crary. Considera il seguente codice, che la limitazione del valore ti impedirà di scrivere in ML:

let
   val x: 'a option ref = ref NONE
in
   (x := SOME 5; x := SOME "Hello")  
end

Confrontalo con il seguente codice, che è totalmente privo di problemi:

let
   val x: unit -> 'a option ref = fn () => ref NONE
in
   (x () := SOME 5; x () := SOME "Hello")  
end

Sappiamo cosa fa il secondo esempio: crea due nuove celle ref contenenti NONE, quindi inserisce SOME 5la prima (an int option ref), quindi inserisce SOME "Hello"la seconda (a string option ref).

xxα.arbitro(opzione(α))xΛα.arbitro[α](NESSUNA)

Ciò suggerirebbe che un comportamento "buono" del primo esempio è comportarsi esattamente allo stesso modo del secondo esempio: creare un'istanza del lambda a livello di tipo due volte diverse. La prima volta xcon intcui creiamo un'istanza , che causerà la x [int]valutazione di una cella di riferimento NONEe quindi SOME 5. La seconda volta xcon stringcui creiamo un'istanza , il che farà caso x [string]per valutare una cella di riferimento ( diversa! ) NONEE quindi SOME "Hello". Questo comportamento è "corretto" (tipo sicuro), ma non è sicuramente quello che un programmatore si aspetterebbe, ed è per questo che abbiamo la limitazione del valore in ML, per evitare che i programmatori affrontino questo tipo di comportamento inaspettato.


1
La versione desugared di e1; e2contiene una parentesi non corrispondente e un punto e virgola (che dovrebbe definire). Volevi dire (fn _ => e2) e1?
Tsuyoshi Ito,

Right-o, Tsuyoshi: risolto.
Rob Simmons,

Il tuo ultimo paragrafo dice in sostanza: la semantica (operativa) e il sistema di tipi non corrispondono, uno deve essere corretto e scegliamo di risolvere quest'ultimo.
Radu GRIGore,

Radu: certo, sono d'accordo con quel riassunto.
Rob Simmons,

3

La tesi di dottorato di Xavier Leroy è un buon inizio.


1
La tesi non copre loop imperativi, condizionali, IO e istruzioni composte, vero? Il motivo principale della mia domanda era che non riuscivo a trovare documenti che trattassero questi argomenti. I documenti sui compiti di battitura sono abbondanti.
nponeccop,

0

Mi dispiace per il fatto che non abbia risposto alla mia domanda, ma il riferimento in questione è

Una proposta per Standard ML , Milner, 1983

La parte 6 "Forme derivate standard" copre in modo piuttosto esteso la dissoluzione di costrutti imperativi. E finora è il primo riferimento di queste trasformazioni in gran parte ovvie che ho potuto trovare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.