En mi búsqueda de trabajos de investigación sobre sistemas de tipos para lenguajes imperativos, solo encuentro soluciones para un lenguaje con referencias mutables pero sin estructuras de control imperativo genuinas como operadores compuestos, bucles o condicionales.
Por lo tanto, no está claro cómo se puede implementar un lenguaje imperativo con inferencia de tipo parcial como http://rust-lang.org .
Los documentos no mencionan tipos parametrizados, como List of aporque los tipos parametrizados son una extensión trivial del sistema de tipos Hindley-Milner: solo el algoritmo de unificación debe extenderse, y el resto de la inferencia funciona como es. Sin embargo, las asignaciones no se pueden agregar trivialmente porque surgen paradojas, por lo que se deben aplicar técnicas especiales como la restricción del valor ML.
¿Puede recomendar algún documento o libro que describa un sistema de tipos para un lenguaje con bucles imperativos, condicionales, IO y declaraciones compuestas?

let val x = ref 9 in while !x>0 do (print (Int.toString (!x)); x := !x-1) end. Entonces, a nivel de una pregunta de investigación, ¿la respuesta que está buscando es "aplicar técnicas desarrolladas en Caml / SML, incluida la restricción de valor"?Respuestas:
Si está buscando una referencia ordenada y funcional para la inferencia de tipos, estoy un poco parcial con respecto a la " Inferencia de tipos en contexto " de Gundry, McBride y McKinna de 2010 , aunque puede que esta no sea una buena guía para ninguna implementación real existente .
Creo que parte de la respuesta es que, más allá de la restricción de valor, realmente no hay tanta dificultad para adaptar la inferencia de tipo Hindley-Milner a los idiomas imperativos: si define
e1; e2como azúcar sintáctico(fn _ => e2) e1y definewhile e1 do e2como azúcar sintáctico parawhiledo e1 (fn () => e2), ¿dóndewhiledoes un regular función recursivaentonces todo funcionará bien, incluida la inferencia de tipos.
En cuanto a que la restricción de valor es una técnica especial, me gusta la siguiente historia; Estoy bastante seguro de que lo recogí de Karl Crary. Considere el siguiente código, que la restricción de valor le impedirá escribir en ML:
Compárelo con el siguiente código, que no tiene ningún problema:
Sabemos lo que hace el segundo ejemplo: crea dos nuevas celdas de referencia que contienen
NONE, luego colocaSOME 5la primera (aint option ref), luego colocaSOME "Hello"la segunda (astring option ref).xxxEsto sugeriría que un comportamiento "bueno" del primer ejemplo es comportarse exactamente de la misma manera que el segundo ejemplo: instanciar la lambda de nivel de tipo dos veces diferentes. La primera vez que instanciamos
xconint, lo que hará que sex [int]evalúe a una celda de referenciaNONEy luegoSOME 5. La segunda vez que instanciamosxconstring, lo que hará que sex [string]evalúe en una celda de referencia ( ¡diferente! )NONEY luegoSOME "Hello". Este comportamiento es "correcto" (tipo seguro), pero definitivamente no es lo que un programador esperaría, y es por eso que tenemos la restricción de valor en ML, para evitar que los programadores se enfrenten a este tipo inesperado de comportamiento.fuente
e1; e2contiene un paréntesis no coincidente y un punto y coma (que se supone que debe definir). Quiso decir(fn _ => e2) e1?La tesis doctoral de Xavier Leroy es un buen comienzo.
fuente
Lo siento por responder mi propia pregunta, pero la referencia en cuestión es
Una propuesta para el estándar ML , Milner, 1983
La Parte 6 "Formularios Derivados Estándar" cubre el descortezado de las construcciones imperativas de manera bastante extensa. Y hasta ahora es la referencia más temprana de estas transformaciones en gran medida obvias que pude encontrar.
fuente