tipos tiene que programas programacion partes lenguaje interpretes funcion fases ejemplos compiladores compilador compiler-construction haskell ocaml functional-programming

compiler-construction - programas - que funcion tiene un compilador en un lenguaje de programacion



¿Por qué es más fácil escribir un compilador en un lenguaje funcional? (7)

Básicamente, un compilador es una transformación de un conjunto de códigos a otro: de origen a IR, de IR a IR optimizado, de IR a ensamblaje, etc. Este es precisamente el tipo de cosa para la que están diseñados los lenguajes funcionales: una función pura es solo una transformación de una cosa a otra. Las funciones imperativas no tienen esta calidad. Aunque puede escribir este tipo de código en un lenguaje imperativo, los lenguajes funcionales están especializados para ello.

He estado pensando en esta pregunta por mucho tiempo, pero realmente no pude encontrar la respuesta en Google y una pregunta similar sobre Stackoverflow. Si hay un duplicado, lo siento por eso.

Mucha gente parece decir que escribir compiladores y otras herramientas de lenguaje en lenguajes funcionales como OCaml y Haskell es mucho más eficiente y fácil que escribirlos en idiomas imperativos.

¿Es esto cierto? Y si es así, ¿por qué es tan eficiente y fácil escribirlos en idiomas funcionales en lugar de en un lenguaje imperativo, como C? Además, ¿no es una herramienta de lenguaje en un lenguaje funcional más lenta que en algún lenguaje de bajo nivel como C?


Muchas tareas de compilación son coincidencia de patrones en estructuras de árbol.

Tanto OCaml como Haskell tienen capacidades de coincidencia de patrones potentes y concisas.

Es más difícil agregar coincidencia de patrones a lenguajes imperativos, ya que cualquier valor que se evalúe o extraiga para que coincida con el patrón debe ser libre de efectos secundarios.


Muchas veces un compilador trabaja mucho con árboles. El código fuente se analiza en un árbol de sintaxis. Ese árbol podría transformarse en otro árbol con anotaciones de tipo para realizar la comprobación de tipos. Ahora puede convertir ese árbol en un árbol que solo contenga elementos del lenguaje central (convirtiendo las notaciones sintácticas tipo azúcar en una forma no apareada). Ahora puede realizar varias optimizaciones que son básicamente transformaciones en el árbol. Después de eso, probablemente crees un árbol en una forma normal y luego iteras sobre ese árbol para crear el código de objetivo (ensamblaje).

El lenguaje funcional tiene funciones como la coincidencia de patrones y un buen soporte para la recursión eficiente, lo que facilita el trabajo con árboles, por lo que generalmente se los considera buenos lenguajes para escribir compiladores.


Parece que todos olvidaron otra razón importante. Es bastante fácil escribir un lenguaje específico de dominio incrustado (EDSL) para analizadores que se parecen mucho (E) a BNF en código normal. Los combinadores de analizadores como Parsec son bastante fáciles de escribir en lenguajes funcionales utilizando funciones de orden superior y composición de funciones. No solo es más fácil pero muy elegante.

Básicamente, usted representa los analizadores genéricos más simples como funciones simples y tiene operaciones especiales (generalmente funciones de orden superior) que le permiten componer estos analizadores primitivos en analizadores sintácticos más complicados y específicos para su gramática.

Esta no es la única forma de hacer frameworks parer de curso.


Una posibilidad es que un compilador tenga que tratar con mucho cuidado una gran cantidad de casos de esquina. Obtener el código correcto a menudo es más fácil mediante el uso de patrones de diseño que estructuran la implementación de una manera que es paralela a las reglas que implementa. A menudo eso termina siendo un diseño declarativo (coincidencia de patrones, "dónde") en lugar de imperativo (secuenciación, "cuando") y, por lo tanto, más fácil de implementar en un lenguaje declarativo (y la mayoría de ellos son funcionales).


Ver también

Patrón de diseño F #

FP agrupa cosas ''por operación'', mientras que OO agrupa cosas ''por tipo'', y ''por operación'' es más natural para un compilador / intérprete.


Un factor importante a tener en cuenta es que una gran parte de cualquier proyecto de compilación es cuando puede autoevaluar el compilador y "comer su propia comida para perros". Por esta razón, cuando observa idiomas como OCaml, donde están diseñados para la investigación de idiomas, tienden a tener excelentes características para problemas de compilación.

En mi último trabajo al estilo del compilador utilizamos OCaml exactamente por esta razón mientras manipulaba el código C, era simplemente la mejor herramienta para la tarea. Si la gente de INRIA hubiera construido OCaml con diferentes prioridades, podría no haber sido tan buena opción.

Dicho esto, los lenguajes funcionales son la mejor herramienta para resolver cualquier problema, por lo que lógicamente se deduce que son la mejor herramienta para resolver este problema en particular. QED.

/ me: vuelve a mis tareas de Java un poco menos alegremente ...