Compilador para el lenguaje de programación Haskell
Glasgow Haskell Compiler ( GHC ) es un compilador de código nativo o de máquina para el lenguaje de programación funcional Haskell . [5] Proporciona un entorno de software multiplataforma para escribir y probar código Haskell y admite muchas extensiones, bibliotecas y optimizaciones que agilizan el proceso de generación y ejecución de código. GHC es el compilador Haskell más utilizado. [6] Es un software gratuito y de código abierto publicado bajo una licencia BSD .
Historia
GHC comenzó originalmente en 1989 como un prototipo, escrito en Lazy ML (LML) por Kevin Hammond en la Universidad de Glasgow . Más tarde ese año, el prototipo fue completamente reescrito en Haskell, excepto por su analizador , por Cordelia Hall, Will Partain y Simon Peyton Jones. Su primera versión beta fue el 1 de abril de 1991. Las versiones posteriores agregaron un analizador de estrictez y extensiones de lenguaje como E/S monádica , matrices mutables, tipos de datos no encapsulados, modelos de programación concurrente y paralela (como memoria transaccional de software y paralelismo de datos ) y un generador de perfiles . [2]
Peyton Jones y Marlow se trasladaron posteriormente a Microsoft Research en Cambridge , donde continuaron siendo los principales responsables del desarrollo de GHC. GHC también contiene código de más de trescientos colaboradores. [1]
Desde 2009 hasta aproximadamente 2014, las contribuciones de terceros a GHC fueron financiadas por el Industrial Haskell Group. [7]
Nombres de GHC
Desde los primeros lanzamientos, el sitio web oficial [8] se ha referido a GHC como The Glasgow Haskell Compiler , mientras que en la versión ejecutable command se identifica como The Glorious Glasgow Haskell Compilation System . [9] Esto se ha reflejado en la documentación. [10] Inicialmente, tenía el nombre interno de The Glamorous Glasgow Haskell Compiler . [11]
Arquitectura
GHC está escrito en Haskell , [12] pero el sistema de ejecución de Haskell, esencial para ejecutar programas, está escrito en C y C-- .
El front-end de GHC , que incorpora el analizador léxico , el analizador sintáctico y el verificador de tipos , está diseñado para preservar la mayor cantidad posible de información sobre el lenguaje fuente hasta que se complete la inferencia de tipos , con el objetivo de proporcionar mensajes de error claros a los usuarios. [2] Después de la verificación de tipos, el código Haskell se desglosa en un lenguaje intermedio tipado conocido como "Core" (basado en System F , extendido con expresiones let
y case
). Core se ha extendido para admitir tipos de datos algebraicos generalizados en su sistema de tipos , y ahora se basa en una extensión de System F conocida como System F C. [13]
En la tradición de la compilación dirigida por tipos, el simplificador de GHC, o "extremo medio", donde se realizan la mayoría de las optimizaciones implementadas en GHC, está estructurado como una serie de transformaciones de fuente a fuente en el código Core. Los análisis y transformaciones realizados en esta etapa del compilador incluyen análisis de demanda (una generalización del análisis de estrictez ), aplicación de reglas de reescritura definidas por el usuario (incluido un conjunto de reglas incluidas en las bibliotecas estándar de GHC que realizan la fusión foldr/build ), desdoblamiento (llamado " inlining " en compiladores más tradicionales), let-floating, un análisis que determina qué argumentos de función se pueden desempaquetar, análisis de resultados de productos construidos , especialización de funciones sobrecargadas y un conjunto de transformaciones locales más simples como plegado constante y reducción beta . [14]
El back end del compilador transforma el código Core en una representación interna de C--, a través de un lenguaje intermedio STG (abreviatura de "Spineless Tagless G-machine"). [15] El código C-- puede tomar una de tres rutas: se imprime como código C para compilación con GCC , se convierte directamente en código de máquina nativo (la tradicional fase de " generación de código "), o se convierte a LLVM IR para compilación con LLVM. En los tres casos, el código nativo resultante se vincula finalmente con el sistema de ejecución de GHC para producir un ejecutable.
Idioma
GHC cumple con los estándares de lenguaje, tanto Haskell 98 [16] como Haskell 2010. [ 17]
También admite muchas extensiones opcionales al estándar Haskell: por ejemplo, la biblioteca de memoria transaccional de software (STM), que permite transacciones de memoria componibles .
Extensiones para Haskell
Se han propuesto muchas extensiones de Haskell que proporcionan características no descritas en la especificación del lenguaje o que redefinen construcciones existentes. Por ello, es posible que no todas las implementaciones de Haskell admitan cada extensión. Hay un esfuerzo continuo [18] para describir las extensiones y seleccionar aquellas que se incluirán en futuras versiones de la especificación del lenguaje.
Las extensiones [19] compatibles con el compilador Glasgow Haskell incluyen:
- Tipos y operaciones sin encapsular. Representan los tipos de datos primitivos del hardware subyacente, sin la indirección de un puntero al montón ni la posibilidad de una evaluación diferida. El código con uso intensivo de recursos numéricos puede ser significativamente más rápido cuando se codifica utilizando estos tipos.
- La capacidad de especificar una evaluación estricta para un valor, un enlace de patrón o un campo de tipo de datos.
- Sintaxis más conveniente para trabajar con módulos, patrones, comprensiones de listas , operadores, registros y tuplas.
- Azúcar sintáctico para realizar cálculos con flechas y valores monádicos definidos de forma recursiva . Ambos conceptos amplían la notación monádica do proporcionada en Haskell estándar.
- Un sistema de tipos y clases de tipos significativamente más potente, descrito a continuación.
- Plantilla Haskell , un sistema para metaprogramación en tiempo de compilación . Se pueden escribir expresiones para producir código Haskell en forma de árbol de sintaxis abstracta . Estas expresiones se comprueban y evalúan en tiempo de compilación; el código generado se incluye entonces como si fuera parte del código original. Junto con la capacidad de reflexionar sobre las definiciones, esto proporciona una herramienta poderosa para futuras extensiones del lenguaje.
- Cuasi-cita, que permite al usuario definir una nueva sintaxis concreta para expresiones y patrones. La cuasi-cita es útil cuando un metaprograma escrito en Haskell manipula código escrito en un lenguaje distinto de Haskell.
- Clases de tipos genéricas , que especifican funciones únicamente en términos de la estructura algebraica de los tipos en los que operan.
- Evaluación paralela de expresiones utilizando múltiples núcleos de CPU. Esto no requiere generar subprocesos explícitamente. La distribución del trabajo se realiza de manera implícita, según las anotaciones proporcionadas en el programa.
- Pragmas del compilador para dirigir optimizaciones como la expansión en línea y la especialización de funciones para tipos particulares.
- Las reglas de reescritura personalizables son reglas que describen cómo reemplazar una expresión con una expresión equivalente, pero evaluada de manera más eficiente. Estas se utilizan dentro de las bibliotecas de estructuras de datos centrales para proporcionar un mejor rendimiento en todo el código a nivel de aplicación. [20]
- Sintaxis de registro de puntos. Proporciona una sintaxis sencilla para acceder a los campos de un registro (posiblemente anidado) que es similar a la sintaxis de muchos otros lenguajes de programación. [21]
Extensiones del sistema de tipos
Un sistema de tipos estáticos expresivos es una de las principales características definitorias de Haskell. Por ello, gran parte del trabajo de extensión del lenguaje se ha dirigido a los tipos de datos y las clases de tipos .
El compilador Glasgow Haskell admite un sistema de tipos extendido basado en el sistema teórico FC . [ 13] Las principales extensiones del sistema de tipos incluyen:
- Polimorfismo impredicativo y de rango arbitrario . Básicamente, un constructor de tipo de datos o función polimórfica puede requerir que uno de sus argumentos también sea polimórfico.
- Tipos de datos algebraicos generalizados . Cada constructor de un tipo de datos polimórfico puede codificar información en el tipo resultante. Una función que realiza una búsqueda de patrones en este tipo puede utilizar la información de tipo por constructor para realizar operaciones más específicas en los datos.
- Tipos existenciales . Se pueden utilizar para "agrupar" algunos datos junto con operaciones sobre esos datos, de manera que las operaciones se puedan utilizar sin exponer el tipo específico de los datos subyacentes. Este tipo de valor es muy similar a un objeto , tal como se encuentra en los lenguajes de programación orientados a objetos .
- Tipos de datos que en realidad no contienen ningún valor. Pueden ser útiles para representar datos en metaprogramación a nivel de tipo .
- Familias de tipos : funciones definidas por el usuario de tipos a tipos. Mientras que el polimorfismo paramétrico proporciona la misma estructura para cada instancia de tipo, las familias de tipos proporcionan polimorfismo ad hoc con implementaciones que pueden diferir entre instancias. Los casos de uso incluyen contenedores de optimización conscientes del contenido y metaprogramación a nivel de tipo.
- Parámetros de función implícitos que tienen un alcance dinámico . Se representan en tipos de forma muy similar a las restricciones de clase de tipo.
- Tipos lineales (GHC 9.0)
Las extensiones relacionadas con las clases de tipos incluyen:
- Una clase de tipo puede parametrizarse en más de un tipo. Por lo tanto, una clase de tipo puede describir no solo un conjunto de tipos, sino también una relación n -aria entre tipos.
- Dependencias funcionales , que restringen partes de esa relación para que sean una función matemática de los tipos. Es decir, la restricción especifica que algún parámetro de la clase de tipo se determina por completo una vez que se fija algún otro conjunto de parámetros. Esto guía el proceso de inferencia de tipos en situaciones en las que, de lo contrario, habría ambigüedad.
- Se han relajado considerablemente las reglas sobre la forma permitida de las instancias de clases de tipos. Cuando se habilitan por completo, el sistema de clases de tipos se convierte en un lenguaje Turing-completo para programación lógica en tiempo de compilación.
- Las familias de tipos, como se describió anteriormente, también pueden estar asociadas con una clase de tipos.
- La generación automática de determinadas instancias de clases de tipos se amplía de varias maneras. Se admiten nuevas clases de tipos para programación genérica y patrones de recursión comunes. Además, cuando se declara un nuevo tipo como isomorfo a un tipo existente, cualquier instancia de clase de tipos declarada para el tipo subyacente puede elevarse al nuevo tipo "gratis".
Portabilidad
Existen versiones de GHC para varios sistemas o plataformas informáticas , incluidos Windows y la mayoría de las variedades de Unix (como Linux , FreeBSD , OpenBSD y macOS ). [22] GHC también se ha adaptado a varias arquitecturas de procesador diferentes . [22]
Véase también
Referencias
- ^ ab "El equipo de GHC". Haskell.org . Consultado el 1 de septiembre de 2016 .
- ^ abc Hudak, P.; Hughes, J.; Peyton Jones, S .; Wadler, P. (junio de 2007). "Una historia de Haskell: ser perezoso con las clases" (PDF) . Procedimientos de la Tercera Conferencia de Historia de los Lenguajes de Programación SIGPLAN de ACM (HOPL-III) . Consultado el 1 de septiembre de 2016 .
- ^ "Descargar – El compilador Glasgow Haskell". Haskell.org .
- ^ ab "Desuso de las plataformas Darwin y Windows de 32 bits". Equipo GHC.
- ^ "Guía del usuario del glorioso sistema de compilación Haskell de Glasgow". Haskell.org . Consultado el 27 de julio de 2014 .
- ^ "Resultados de la encuesta sobre el estado de Haskell en 2017". taylor.fausak.me . 15 de noviembre de 2017 . Consultado el 11 de diciembre de 2017 .
- ^ "Industrial Haskell Group". Haskell.org . 2014 . Consultado el 1 de septiembre de 2016 .
- ^ "GHC El compilador Glasgow Haskell". Haskell.org . Consultado el 14 de enero de 2022 .
- ^ "Repositorio: configure.ac". gitlab.haskell.org . 12 de enero de 2022 . Consultado el 14 de enero de 2022 .
- ^ "Guía del usuario del glorioso sistema de compilación Glasgow Haskell, versión 7.6.3". downloads.haskell.org . Consultado el 14 de enero de 2022 .
- ^ "ghc-0.29-src.tar.gz" ( tar gzip ) . downloads.haskell.org . Archivo: ghc-0.29/ghc/PATCHLEVEL . Consultado el 14 de enero de 2022 .
- ^ "Comentario de GHC: El compilador". Haskell.org . 23 de marzo de 2016. Archivado desde el original el 23 de marzo de 2016. Consultado el 26 de mayo de 2016 .
- ^ ab Sulzmann, M.; Chakravarty, MMT; Peyton Jones, S .; Donnelly, K. (enero de 2007). "Sistema F con coerciones de igualdad de tipos". Procedimientos del taller de la ACM sobre tipos en el diseño e implementación de lenguajes (TLDI) .
- ^ Peyton Jones, S. (abril de 1996). "Compilación de Haskell mediante transformación de programas: un informe desde las trincheras". Procedimientos del Simposio Europeo de Programación (ESOP) .
- ^ Peyton Jones, S. (abril de 1992). "Implementación de lenguajes funcionales perezosos en hardware estándar: la máquina G sin etiquetas y sin espinas, versión 2.5". Revista de programación funcional . 2 (2): 127–202. doi :10.1017/S0956796800000319.
- ^ "Lenguaje y bibliotecas Haskell 98: informe revisado". Haskell.org . Consultado el 28 de enero de 2007 .
- ^ "Haskell 2010 Language Report". Haskell.org . Consultado el 30 de agosto de 2012 .
- ^ "Bienvenido a Haskell (Haskell Prime)". Haskell.org . Archivado desde el original el 20 de febrero de 2016. Consultado el 26 de mayo de 2016 .
- ^ "Características del lenguaje GHC". Haskell.org . Archivado desde el original el 29 de junio de 2016. Consultado el 25 de mayo de 2016 .
- ^ Coutts, D.; Leshchinskiy, R.; Stewart, D. (abril de 2007). "Fusión de flujos: de listas a flujos y a nada en absoluto". Procedimientos de la Conferencia internacional sobre programación funcional (ICFP) de la ACM SIGPLAN . Archivado desde el original el 23 de septiembre de 2007.
- ^ Mitchell, Neil; Fletcher, Shayne (3 de mayo de 2020). «Sintaxis de registro de puntos». ghc-proposals . GitHub . Consultado el 30 de junio de 2020 .
- ^ Plataformas en gitlab.haskell.org
Enlaces externos