¿Es el compilador para el tipo dependiente mucho más difícil que un intérprete?

11

He estado aprendiendo algo sobre la implementación de tipos dependientes, como este tutorial , pero la mayoría de ellos está implementando intérpretes. Mi pregunta es, parece que implementar un compilador para el tipo dependiente es mucho más difícil que un compilador, porque realmente puede evaluar los argumentos del tipo dependiente para la verificación de tipos.

Entonces

  • ¿Es correcta mi ingenua impresión?
  • Si es correcto, ¿algún ejemplo / recurso sobre la implementación de un lenguaje comprobado estáticamente que admita el tipo dependiente?
molikto
fuente
No, ya que puede reducir el problema de compilación de tipos dependientes a un problema conocido: (1) verifique el programa utilizando un intérprete; (2) extraer el programa a OCaml / Haskell / lo que sea; (3) compilar usando ocamlopto GHC :-) (Este es el enfoque de Coq y Agda, por cierto.)
xrq

Respuestas:

12

¡Esta es una pregunta interesante! Como sugiere la respuesta de Anthony, uno puede usar los enfoques habituales para compilar un lenguaje funcional no dependiente, siempre que ya tenga un intérprete para evaluar los términos para la verificación de tipo .

Este es el enfoque adoptado por Edwin Brady. Ahora, esto es conceptualmente más simple, pero pierde las ventajas de velocidad de la compilación cuando se realiza la verificación de tipo. Esto se ha abordado de varias maneras.

Primero, uno puede implementar una máquina virtual que compila términos para codificar en bytes sobre la marcha para realizar la verificación de conversión. Esta es la idea detrás vm_computeimplementada en Coq por Benjamin Gregoire . Aparentemente también existe esta tesis de Dirk Kleeblatt sobre este tema exacto, pero desciende el código de máquina real en lugar de una máquina virtual.

En segundo lugar, uno puede generar código en un lenguaje más convencional que, después de la ejecución, verifica todas las conversiones necesarias para verificar un programa mecanografiado de forma dependiente. Esto significa que podemos usar Haskell, por ejemplo, para verificar el tipo de un módulo Agda. El código puede compilarse y ejecutarse, y si acepta, entonces se puede suponer que el código en el lenguaje de tipo dependiente está bien escrito (salvo la implementación y los errores del compilador). Escuché por primera vez este enfoque sugerido por Mathieu Boesflug .

cody
fuente
1
Un poco irónico: ¿por qué se molestaría en escribir un compilador si tiene un intérprete haciendo la verificación de tipo? Después de todo, a la mayoría (¿todos?) Usuarios serios de lenguajes de programación mecanografiados de forma dependiente solo les importa el verificador de tipos, usando el lenguaje como asistente de prueba. Ciertamente, nunca he ejecutado ninguno de mis programas Agda o Coq. Entonces, si le importa la velocidad, ¿no le gustaría compilar las conversiones de tipo?
Martin Berger
2
Las soluciones 2 y 3 abordan este problema: compila código que verifica el buen tipeo (y en particular realiza conversiones de tipo). Mi segundo comentario es que realmente desea ejecutar código tipeado de forma dependiente en algunas situaciones (consulte Idris, Ur / Web).
cody
1
Además: hasta cierto punto, la solución 1 también lo aborda, difuminando las líneas entre el intérprete y el compilador.
cody
1
Me pregunto si la técnica de proyecciones de futurama podría usarse para acelerar el intérprete, terminando efectivamente con un compilador.
Steven Shaw
1
Lo único que he visto es Unison unisonweb.org/2017-10-13/scala-world.html
Steven Shaw
10

La tesis doctoral de Edwin Brady describe cómo construir un compilador para un lenguaje de programación de tipo dependiente. No soy un experto, pero diría que no es extremadamente difícil que implementar un compilador similar a System F. Muchos de los principios son bastante similares y algunos son iguales (por ejemplo, compilación de supercombinador). La tesis cubre muchas otras preocupaciones.

Antonio
fuente