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 a
porque 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; e2
como azúcar sintáctico(fn _ => e2) e1
y definewhile e1 do e2
como azúcar sintáctico parawhiledo e1 (fn () => e2)
, ¿dóndewhiledo
es 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 5
la primera (aint option ref
), luego colocaSOME "Hello"
la segunda (astring option ref
).x
x
x
Esto 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
x
conint
, lo que hará que sex [int]
evalúe a una celda de referenciaNONE
y luegoSOME 5
. La segunda vez que instanciamosx
constring
, lo que hará que sex [string]
evalúe en una celda de referencia ( ¡diferente! )NONE
Y 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; e2
contiene 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