Programación Orientada al Lenguaje

Programación orientada al lenguaje (LOP) ( Programación orientada al idioma inglés  ), también desarrollo divergente ( desarrollo intermedio en inglés ), también abstracción del metalenguaje , también desarrollo basado en un lenguaje específico de dominio ( desarrollo basado en DSL en inglés ) [1] - paradigma de programación , que consiste en dividir el proceso de desarrollo de software en la etapa de desarrollo de lenguajes específicos de dominio (DSL) y describir la solución real del problema usándolos. Las etapas se pueden realizar secuencialmente o en paralelo, una vez o recursivamente [2] [1] ; Los DSL se pueden implementar de forma dependiente o independiente del idioma base y tener una o más implementaciones.   

Lugar y papel en informática

LOP está diseñado para separar complejidades: la parte del código orientada a la máquina (funcionalidad de bajo nivel) y la parte orientada al ser humano (la solución real del problema aplicado) se desarrollan de forma independiente, lo que elimina el crecimiento exponencial de la complejidad resultante de desarrollar todo el proyecto y resuelve el problema de la complejidad como problema fundamental de programación [2] , descrito por Frederick Brooks en el famoso ensayo “ No hay una bala de plata ”, por lo que es imposible aumentar la productividad de los programadores. incluso en un orden de magnitud simplemente mejorando las herramientas de trabajo. La mayoría de las otras ventajas se derivan directamente de esto .

Los méritos de reducir la especialización de los idiomas se discutieron a mediados de la década de 1980 [3] , y los méritos de elevar el nivel de los idiomas mucho antes [4] , pero el desarrollo orientado a DSL se formó como un independiente metodología solo a mediados de la década de 1990 .

El uso de DSL en lugar de lenguajes de propósito general aumenta considerablemente el nivel de abstracción del código, lo que le permite desarrollar de manera rápida y eficiente y crear programas fáciles de entender y mantener; y también hace posible o simplifica significativamente la solución de muchos problemas relacionados con la manipulación de programas ( generación de programas , el estudio de una determinada propiedad de los programas - corrección, eficiencia, etc.) [3] [1] [5] [ 6] . Por otro lado, el desarrollo de un nuevo lenguaje y su implementación efectiva es un problema no trivial de la informática teórica y aplicada .

Entre otros enfoques para el diseño de programas, LOP se destaca por su enfoque mucho más agresivo en acercar la computadora al ser humano. Hay una opinión entre los investigadores de LOP de que en tareas científicas intensivas, un DSL bien diseñado e implementado hace que la comunicación humano-computadora sea mucho más conveniente y productiva que una interfaz gráfica de usuario . Los ejemplos más comúnmente citados son los siguientes lenguajes populares específicos de dominio :

y etc.

Las ventajas de LOP aparecen incluso en los casos en que el DSL no está desarrollado para un uso masivo, sino para resolver una única tarea. Por ejemplo, al desarrollar un sistema para la conversión equivalente automática de programas FermaT , la transición de la programación "plana" en Lisp a LOP recursivo (WSL se implementó en Lisp , MetaWSL se implementó en él y la funcionalidad de destino ya estaba en it) no solo permitió reducir la cantidad total de código de 100 a 16 mil líneas, sino que al mismo tiempo aumentó todas las principales características cualitativas del código e incluso hizo posible resolver problemas que no podrían resolverse de otra manera [2] .

Una comparación simplificada del crecimiento de los costes laborales cuando se utilizan los enfoques tradicionales y orientados al lenguaje permite el gráfico [1] . Como puede ver, LOP es conveniente solo a partir de un cierto umbral de volumen y complejidad de la funcionalidad del sistema de destino.

La mayoría de los investigadores de LOP se basan en lenguajes y metalenguajes funcionales , lo que conduce a un umbral de entrada alto para los desarrolladores. Martin Ward señala la posibilidad de implementar DSL en lenguajes tradicionales, pero solo después de su desarrollo final.

En la corriente principal , a menudo se usa la incorporación de un intérprete en un lenguaje de propósito general (ver Enfoque ), aunque esto no solo se hace sin apelar a los principios de LOP, sino a menudo sin darse cuenta del hecho de su uso como tal. Incrustado con mayor frecuencia: lenguaje de expresiones regulares ( intérprete PCRE ), Lua , SQL , XML . También se ha desarrollado un conjunto de herramientas de programación visual para el uso generalizado de algunas de las ideas de LOP.

Muchos investigadores ven el objetivo de LOP como desdibujar por completo los límites entre un modelo matemático y su implementación en una computadora y hacer posible el desarrollo de software por parte de especialistas en la materia que no tienen conocimientos específicos en programación [1] [6] :

-- проверка вхождения точки в регион:
inRegion :: Point -> Region -> Bool
p ‘inRegion‘ r = r p
...
Al capturar con precisión la semántica del dominio, incluso los no programadores pueden comprender gran parte del código. En un experimento encargado por el Naval Surface Warfare Center, personas que no estaban familiarizadas con Haskell captaron los conceptos básicos sobre la marcha. Algunos incluso expresaron su incredulidad de que este código fuera realmente ejecutable.
(De hecho, a pesar de la presencia de esta última oración en el texto, uno de los revisores del primer borrador de este trabajo expresó su descontento con el hecho de que “ se afirma que el trabajo es un discurso sobre la sintaxis y la semántica, pero su contenido es principalmente relacionado con la sintaxis (como, por ejemplo, la definición inRegion), y no se hace distinción entre matemáticas y programación ". Pero, de hecho, esta definición inRegiones completamente semántica. Además, el razonamiento ecuacional [7] ... línea entre matemáticas y programación: los programas pueden ser considerados como especificaciones. Esto es especial porque extiende el uso de métodos formales.)

Texto original  (inglés)[ mostrarocultar] ...
Debido a que la semántica del dominio se captura de manera concisa, es posible que incluso los no programadores entiendan gran parte del código. En el experimento del Centro Naval de Guerra de Superficie, aquellos que no estaban familiarizados con Haskell pudieron comprender los conceptos de inmediato. Algunos incluso expresaron su incredulidad de que el código fuera realmente ejecutable.
(De hecho, a pesar de la presencia de esta última oración, un revisor del primer borrador de este artículo se quejó de que “el artículo afirma estar interesado tanto en la sintaxis como en la semántica, pero los detalles presentados son en su mayoría sintácticos (por ejemplo, la definición inRegion), y el documento no intenta distinguir entidades matemáticas y programáticas". Pero, de hecho, esta definición de inRegiones completamente semántica. Además, el razonamiento ecuacional [7] ... permite difuminar la distinción entre entidades matemáticas y programáticas: los programas pueden verse como especificaciones (esta es una característica, ya que mejora la aplicación de métodos formales). — Paul Hudak, "Herramientas y lenguajes específicos de dominio modular" [1]

Enfoque

El enfoque se basa en la idea de que un lenguaje especialmente diseñado para una tarea dada proporcionará indicadores de calidad de código obviamente más altos que cualquier lenguaje de propósito general [1] [6] , y que para resolver problemas industriales complejos será más eficiente inventar lenguaje más fácil de entender (orientado a los humanos [8] o que encapsula con precisión el conocimiento de la materia [2] [1] ), en lugar de superar las dificultades de usar uno existente, incluso uno que tiene sus raíces en la industria [4] .

La mayoría de los investigadores hablan de LOP como una transición de toda la industria de desarrollo de software al uso de lenguajes basados ​​en texto de 4ª y 5ª generación [8] , pero algunos se centran en el uso de lenguajes visuales [9] [10 ] .

Los principales problemas del enfoque son encontrar formas de crear rápidamente una implementación del DSL inventado para comenzar a desarrollar la solución real al problema y garantizar un buen rendimiento computacional del DSL .

Un lenguaje de dominio específico, como cualquier lenguaje de programación en general, se define por el alfabeto , la gramática , la semántica y la psicolingüística , sin embargo, dependiendo de la forma en que se implemente el DSL, el rol y la relación de estos niveles pueden ser desdibujados y/o heredados de el idioma de su implementación.

Diferentes autores enfatizan diferentes formas de desarrollar lenguajes específicos de dominio:

Cuando se utilizan macroherramientas, a su vez, existe una distinción entre la metaprogramación de plantilla y la interpretación estática de varias etapas [13] [17] [18] [5] .

Los métodos tercero y cuarto tienen una ventaja fundamental sobre los dos primeros: DSL no reemplaza, sino que amplía el lenguaje de propósito general [14] [1] [19] [20] , reutilizando todo el conjunto de herramientas del lenguaje base, comenzando con el analizador , debido a que:

Muchos autores se centran en la incrustación eficiente (sin interpretación) en el lenguaje de ciertas características inicialmente ausentes para su adaptación a ciertas tareas [15] [16] , que luego pueden servir como base para la incrustación pura de DSL [21] . Se presta una atención considerable al uso de continuaciones para desarrollar DSL con semántica no determinista ( Steel , Wend , Felleisen , Ramsey , Reppy y otros).

Aplicaciones del enfoque y autoaplicabilidad

Una subespecie importante de LOP es la programación de usuarios , que permite que una variedad de personas que no tienen idea de informática resuelvan de manera efectiva muchos problemas aplicados. El papel de esta aplicación de LOP es tan grande que quizás el lenguaje de programación más común en el mundo en la práctica son las herramientas de diseño de hojas de cálculo ( sp.  spreadsheets ) [6] .

Dependiendo de la interpretación del término " metaprogramación " (MP) y la forma en que se implementa el DSL, LOP es la quintaesencia de MT o MT es una de las formas de implementar LOP. La última opción es más aplicable en el caso de incorporar DSL en un lenguaje de propósito general a través de un macro subconjunto de este último [13] . Cuando se usan herramientas de desarrollo visual DSL [9] [10] , estas definiciones son sinónimas, porque La programación visual en sí misma es la forma más simple de MT. Considerar MT como una autoaplicación de LOP significa:

Caja de herramientas

Para desarrollar traductores independientes, los generadores lexer y parser se utilizan ampliamente en función de la definición de la gramática del DSL de destino utilizando BNF y expresiones regulares :

y otros.

Cuando se compila un DSL independiente, el código nativo o incluso el ensamblador rara vez se elige como la plataforma de destino , es más preferible (tanto para reducir la complejidad de implementar el DSL como para aumentar la portabilidad) usar una plataforma de nivel superior:

Las siguientes tecnologías se utilizan para integrar DSL en un lenguaje de propósito general:

La incrustación pura no implica ninguna herramienta adicional, pero impone restricciones bastante severas en la elección del idioma base .

Cuando se utiliza la interpretación estática de varias etapas, la plataforma de destino es la misma que el idioma base [13] [17] [18] [5] .

En el marco de la programación tradicional (en lenguajes heredados de Algol ), el uso de algunas de las ideas de LOP hace posible el kit de herramientas de programación visual , desarrollado en la primera mitad de la década de 2000 [9] [10] [27] [ 28] :

Historia, filosofía, terminología

En la comunidad del lenguaje Lisp , casi desde el momento de su creación, se practicó el uso de herramientas macro para adaptarse a los requerimientos del área temática del problema. Este enfoque, en particular, se describió en detalle en el libro The Structure and Interpretation of Computer Programs . En ocasiones, se han aplicado ideas similares en la comunidad del cuarto idioma . Básicamente, estas decisiones fueron de naturaleza espontánea y, a menudo, pueden clasificarse como decisiones ad hoc [13] .

En la segunda mitad de la década de 1970, se inventó el sistema de tipos Hindley -Milner , que formó la base del lenguaje ML ( una abreviatura de MetaLanguage ) . ML se diseñó originalmente como un DSL para el sistema de prueba de teoremas LCF , pero pronto quedó claro que podría ser un buen lenguaje aplicado de propósito general, mejor que los lenguajes diseñados originalmente para ser lenguajes de propósito general, como depurado en un problema complejo específico [30] [31] . Como consecuencia, generó toda una familia de lenguajes de tipo X-M que han ganado popularidad como lenguajes para el desarrollo de lenguajes ( metalenguajes ) y a menudo se definen como " DSL para semántica denotacional " [1] .

En 1994, Martin  Ward [ 32] dio una descripción detallada de la metodología [2] y propuso los términos " programación orientada al lenguaje " y " desarrollo divergente " (o " desarrollo desde el centro hacia los bordes ", desarrollo medio hacia afuera ), señalando que el enfoque, en diversas formas, se había aplicado muchas veces antes. El término " desarrollo divergente " enfatiza que la capa intermedia ( middle layer ) en el sistema resultante es el DSL desarrollado, a diferencia de los métodos previamente conocidos y aún ampliamente utilizados de " desarrollo de abajo hacia arriba " ( bottom up development [ ), " desarrollo de arriba hacia abajo " ( top down development ) y " desarrollo convergente " ( outide en desarrollo ) que los combina.

Ward también sugirió usar LOP de forma recursiva, aumentando gradualmente la complejidad del sistema que se desarrolla de abajo hacia arriba; y combine LOP con la creación rápida de prototipos desarrollando primero el prototipo de DSL más simple (que se puede hacer muy rápidamente) y la solución más simple usándolo, luego, después de probar el lenguaje, identificar fallas y aclarar requisitos, refinar el DSL y reescribir la solución en un nueva versión del lenguaje, y así sucesivamente de forma iterativa.

Paul Hudak propuso [1] un  método de incrustación puro usando lenguajes type- safe (preferiblemente perezosos como Haskell , pero posiblemente estrictos como ML , aunque en este último caso la implementación resulta un poco más engorrosa y menos natural ) y razonamiento ecuacional [7] desarrollando recursivamente el sistema de arriba a abajo y acumulando código reutilizable en forma de "DSL para el desarrollo de DSL".

El método de incrustación puro dio lugar al término "lenguaje específico de dominio incrustado" ( ing.  Embedded DSL, EDSL ; a veces DSEL ) [1] [8] . Se desarrollaron varios EDSL sobre Haskell para programar aplicaciones en tiempo real interactivas de estilo puramente funcional (Fran, Fruit, FRP y RT-FRP, FAL, Frob, Fvision, Yampa) [33] [19] , que formaron un grupo independiente paradigma - programación reactiva funcional (FRP). Esto demuestra que LOP no es un paradigma de programación cerrado separado, sino que, por el contrario, puede usarse como una herramienta en el desarrollo de nuevos paradigmas.

Standard ML , el dialecto base de ML , ha sido objeto de controversia desde principios de la década de 1990 con respecto a la falta de macrocaracterísticas en el lenguaje [30] . Los críticos argumentaron que la falta de macros era una desventaja, pero los mecanógrafos fuertes objetaron que su ausencia era solo una ventaja. En otro dialecto de ML - OCaml - se propuso una idea de compromiso - parametrización de sintaxis mediante la extracción del analizador en un módulo compilador CamlpX personalizado , a través del cual se desarrolló un conjunto de EDSL para OCaml. Más tarde, apareció una extensión para generar código en tiempo de ejecución: MetaOCaml . A fines de la década de 1990, se propuso la idea de macros con seguridad de tipos como una herramienta para la implementación eficiente de DSL con seguridad de tipos [34] . Esta idea pronto se implementó como extensiones MetaML [13] [17] [18] para Standard ML y Template Haskell [35] para Haskell . En el primer caso, las herramientas macro se consideran únicamente como un intérprete estático de varias etapas; en el segundo, se consideran tanto como el mismo enfoque, y como el cuasi-citado conocido del lenguaje Lisp , y como un subsistema de plantilla , similar al disponible en el lenguaje C++ .

Un estudio de la posibilidad de implementar y aplicar estos enfoques en diferentes lenguajes mostró que C ++ es una herramienta extremadamente inconveniente para desarrollar lenguajes integrados [36] . Sin embargo, C++ permite implementar soluciones de esta dirección, cultivadas y depuradas bajo los auspicios de la programación funcional [5] [37] , lo cual es una rara ventaja para los lenguajes convencionales [5] .

Los datos preliminares de investigación publicados en 2012 mostraron que DSL independiente es más conveniente de usar, mientras que EDSL es más fácil de implementar [8] .

Crítica y comparación con alternativas

Ventajas

El crecimiento de la complejidad de cualquier sistema de software está fundamentalmente limitado por el límite hasta el cual todavía es posible mantener el control sobre él: si la cantidad de información requerida para comprender un componente de este sistema excede la "capacidad" del cerebro de uno persona, entonces este componente no será completamente entendido. Será extremadamente difícil refinarlo o corregir errores, y se puede esperar que cada corrección introduzca nuevos errores debido a este conocimiento incompleto.

Texto original  (inglés)[ mostrarocultar] Existe un límite fundamental en la complejidad de cualquier sistema de software para que siga siendo manejable: si requiere más de "un cerebro completo" de información para comprender un componente del sistema, entonces ese componente no se comprenderá por completo. Será extremadamente difícil realizar mejoras o corregir errores, y es probable que cada corrección introduzca más errores debido a este conocimiento incompleto. — Martin Ward, "Programación orientada al lenguaje" [2]

LOP tiene muchas ventajas sobre el desarrollo "plano" tradicional [2] :

La implementación de lenguajes mediante el desarrollo de traductores independientes es una tarea rutinaria, ya que se ha acumulado una extensa base formal y herramientas basadas en ella ( Lex/Yacc , ANTLR , Parsec [22] ). Por ejemplo, en Parsec, el desarrollo de analizadores para lenguajes con gramática simple (comparable a la gramática de Pascal Wirth ) se realiza en cuestión de horas-hombre [38] [39] .

Desventajas

La programación orientada al lenguaje tiene dos desventajas principales respecto a la programación tradicional, que, sin embargo, no son fundamentales: un alto umbral de entrada para los desarrolladores de lenguajes (reducido a costa de renunciar a la mayoría de las ventajas de la metodología) y la dificultad de asegurar el rendimiento computacional. . Ambas deficiencias son relevantes solo para los desarrolladores de lenguajes específicos de dominio; los usuarios del lenguaje (especialistas en aplicaciones) obtienen un beneficio neto.

Restricciones

El desarrollo de nuevos lenguajes requiere una buena formación teórica y fluidez en lenguajes semánticamente diferentes y sus extensiones. Martin Ward señala que diseñar un buen lenguaje con el potencial de satisfacer a sus usuarios y tener un largo ciclo de vida es una tarea compleja que requiere un alto grado de conocimientos de informática y recomienda que los programadores practiquen constantemente el desarrollo del lenguaje para obtener suficiente experiencia práctica. Además, señala que el objetivo de LOP no es bajar el umbral de entrada para los desarrolladores, sino, por el contrario, empoderar y simplificar el trabajo de los desarrolladores calificados, y ya en el futuro esto lleva a una disminución en la entrada. umbral para los usuarios del sistema, que es necesario para su uso y desarrollo.

Los métodos para incrustar un DSL en un lenguaje de propósito general están lejos de ser aplicables en cualquier idioma, ya que requieren ciertas propiedades de la semántica del lenguaje base en varias combinaciones: un modelo de llamada aplicativo , un sistema de tipo verdaderamente polimórfico o tipificación dinámica (ver polimorfismo ), funciones de orden superior , continuaciones , un subsistema de macroextensión desarrollado, reflexividad , pereza . Estas propiedades no están disponibles inicialmente (o pueden implementarse completamente) de ninguna manera en ningún idioma. En la mayoría de los casos, ambos métodos y sus combinaciones se utilizan en dialectos de idiomas basados ​​​​en cálculo lambda tipificado y no tipificado (un modelo matemático para describir la semántica), a veces con extensiones específicas no estandarizadas: Common Lisp , Scheme , Standard ML , MetaML [ 13] , Alice , OCaml , MetaOCaml , Haskell , Template Haskell , Nemerle . Estos métodos también son aplicables en el lenguaje Forth , aunque los desarrolladores de Forth los utilizan con relativa poca frecuencia. Todos estos idiomas tienen un umbral de entrada alto. Algunos autores señalan la posibilidad de utilizar el tercer método en la corriente principal de C++ , pero se ha criticado la idoneidad de C++ para LOP [36] .

El desarrollo de DSL visual [9] [10] tiene una barrera de entrada baja, pero sacrifica una serie de características de LOP descritas por Ward, Hudak y otros:

  • El concepto de DSL se define como " un lenguaje de programación simplificado (en la mayoría de los casos no completo de Turing ) ";
  • Solo se consideran los DSL con semántica determinista, en particular, Fowler clasifica los modelos de objetos adaptativos como DSL (para que no se desdibujen los límites entre las matemáticas y la semántica, que enfatiza Hudak);
  • No se considera el uso recursivo de LOP, ni la posibilidad de aumentar el número de implementaciones del DSL desarrollado, por lo que la efectividad de la implementación del DSL depende enteramente de los desarrolladores del entorno visual.
Eficiencia

El rendimiento computacional de una implementación DSL "descuidada" puede ser bajo, y una buena optimización puede ser excesivamente costosa. Por supuesto, debido al propósito de algunos DSL, la velocidad no es de importancia fundamental para ellos ( Τ Ε Χ , AutoLisp ). En otros casos, depende tanto del método de implementación como de la plataforma de compilación de destino, y en muchos casos es posible lograr muy buenos resultados. Por ejemplo, Waleed Taha describe [40] la implementación del traductor de lenguaje FRP por el método de generación de código C imperativo , con el cual se desarrollaron aplicaciones en tiempo real para el microcontrolador PIC16C66 de 16 bits [41] . Hudak señala [1] que las implementaciones DSL en línea pura, modulares y de múltiples etapas de Haskell (ver Enfoque ) son extremadamente lentas, ya que cada capa de abstracción produce una desaceleración de 15 a 70 veces, pero debido al uso de técnicas de supercompilación , la velocidad se puede aumentar en tres órdenes de magnitud (de 400 a 2800 veces).

Es posible desarrollar un DSL diseñado para optimizar los diseños utilizados en la lógica de nivel superior. Por ejemplo, el lenguaje OL (Operator Language) [42] se desarrolló para describir algoritmos matemáticos de forma independiente de la plataforma y para simplificar la migración a nuevas arquitecturas de bibliotecas matemáticas con requisitos de alto rendimiento (ver trituradora de números ). El compilador está parametrizado por datos sobre la arquitectura del procesador (soporte para operaciones vectoriales, número de núcleos, etc.) y, en ocasiones, realiza pruebas comparativas automáticas de las opciones de implementación con la elección de la más rápida. Como resultado, un programa en un lenguaje declarativo de muy alto nivel genera un código C muy eficiente (comparable al escrito a mano) que implementa el algoritmo de la manera más eficiente para una arquitectura determinada. En este caso, el ajuste del tamaño de los datos de entrada también se convierte en un componente de la eficiencia; por ejemplo, se puede construir una función rápida para multiplicar matrices de 8x8.

El uso de DSL integrables en lenguajes para los que existen compiladores de optimización global (como Stalin Scheme , MLton ) permite la descomposición de tareas específicas del lenguaje sin pérdida de eficiencia en comparación con otros enfoques de diseño, pero puede imponer restricciones en el desarrollo. ADSL. Esta dirección es objeto de muchos estudios.

Todas estas soluciones son privadas, y la aplicabilidad de cada una de ellas depende de la naturaleza del DSL desarrollado en todos los niveles, o viceversa, le impone requisitos especiales. Así, la correlación de la arquitectura del proyecto con la efectividad de su implementación es una parte integral del problema LOP. Esto también es cierto para otros enfoques de diseño, pero en mucha menor medida.

Notas

  1. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Hudak - Herramientas y lenguajes específicos de dominio modular, 1998 .
  2. 1 2 3 4 5 6 7 8 Ward - Programación orientada al lenguaje, 1994 .
  3. 1 2 Bentley - Pequeños lenguajes, 1986 .
  4. 1 2 Backus - ¿Se puede liberar la programación del estilo vonNeumann?, 1978 , Introducción.
  5. 1 2 3 4 5 Czarnecki, O'Donnell, Striegnitz, Taha: implementación de DSL en metaocaml, plantilla haskell y C++, 2004 .
  6. 1 2 3 4 5 Taha - Idiomas específicos de dominio, 2008 .
  7. 1 2 3 Razonamiento ecuacional
  8. 1 2 3 4 Mernik - Aspectos formales y prácticos de los lenguajes específicos de dominio, 2012 .
  9. 1 2 3 4 Martín Fowler . Language Toolkit: Nueva vida para los idiomas de dominio . — 2005.
  10. 1 2 3 4 Sergey Dmitriev ( JetBrains ). Programación Orientada al Lenguaje: El Próximo Paradigma  // = Revista RSDN . — 2005.
  11. Aho, Seti, Ulmán, 1985, 2001, 2003 .
  12. Desarrollo de aplicaciones con Objective Caml
  13. 1 2 3 4 5 6 7 Ganz, Sabry, Taha: macros como cálculos de varias etapas, 2001 .
  14. 1 2 Shivers - El pequeño lenguaje definitivo, 1996 .
  15. 1 2 Berthomieu - Estilos de programación orientados a objetos en ML, 2000 .
  16. 12 Ramsey , 1990 .
  17. 123Taha , 2004 . _
  18. 123Taha , 2007 . _
  19. 1 2 Cheong - Programación funcional y juegos 3D, 2005 .
  20. Benton - Intérpretes integrados, 2005 .
  21. Schelog, 2003 .
  22. 12 Parsec para Haskell .
  23. Biblioteca MLRISC: un marco para volver a orientar y optimizar los back-end del compilador (enlace descendente) . Consultado el 6 de febrero de 2014. Archivado desde el original el 6 de diciembre de 2013. 
  24. Incrustación de lenguaje de objetos en SML con Quote/Antiquote .
  25. Daniel de Rauglaudre. Camlp4 - Tutorial ((c) 2002 Institut National de Recherche en Informatique et Automatique).
  26. Martín Jambón. Cómo personalizar la sintaxis de OCaml, usando Camlp5 (enlace muerto) ((c) 2005, 2010). Fecha de acceso: 10 de diciembre de 2013. Archivado desde el original el 26 de noviembre de 2013. 
  27. Dmitri Kirillov. Orientación lingüística . Computerra (14 de marzo de 2006). Recuperado: 5 de mayo de 2006.
  28. Ígor Tamashchuk. El idioma específico del dominio en su aplicación es simple (enlace no disponible) (22 de octubre de 2008). Consultado el 24 de octubre de 2008. Archivado desde el original el 15 de diciembre de 2013. 
  29. JetBrains - Entorno de desarrollo de DSL
  30. 1 2 Appel - Una crítica del estándar ML, 1992 .
  31. Paulson, 1991, 1996 , Standard ML, p. once.
  32. Página de inicio de Martin Ward
  33. Elliott, Hudak - Animación reactiva funcional, 1997 .
  34. Bawden - Las macros de primera clase tienen tipos, 2000 .
  35. Sheard, SPJones - Plantilla de metaprogramación para Haskell, 2002 .
  36. 1 2 Czarnecki, O'Donnell, Striegnitz, Taha - Implementación de DSL en metaocaml, plantilla haskell y C++, 2004 , 6. Discusión y observaciones finales, p. Dieciocho: "Texto original  (inglés)[ mostrarocultar] La metaprogramación de plantillas de C++ adolece de una serie de limitaciones, incluidos problemas de portabilidad debido a las limitaciones del compilador (aunque esto ha mejorado significativamente en los últimos años), falta de compatibilidad con la depuración o E/S durante la instanciación de la plantilla, largos tiempos de compilación, errores largos e incomprensibles, pobre la legibilidad del código y el informe de errores deficiente. ".
  37. Daniel Lincke, Patrik Jansson, Marcin Zalewski y Cezar Ionescu. Bibliotecas genéricas en C++ con conceptos de descripciones de dominio de alto nivel en Haskell  // DSLs, Conferencia de trabajo IFIP TC 2. - Oxford, Reino Unido: Springer Berlin Heidelberg Nueva York, Alemania, 2009. - Vol. 15-17 de julio, Editor de volumen WM Taha . - S. 236-261 . - ISBN 3-642-03033-5 , 978-3-642-03033-8 . — ISSN 0302-9743 .
  38. Jonathan Tang. Escriba usted mismo un esquema en 48 horas .
  39. Cómo compilar Pascal en Haskell c. .
  40. Zhanyong Wan, Walid Taha, Paul Hudak. FRP basado en eventos . — Departamento de Ciencias de la Computación, Universidad de Yale.
  41. PIC16C66 - Microcontroladores PIC®
  42. Franz Franchetti, Frédéric de Mesmay, Daniel McFarlin y Markus Püschel, Universidad Carnegie Mellon. Lenguaje del operador: un marco de generación de programas para núcleos rápidos  // Lenguajes específicos de dominio, Conferencia de trabajo IFIP TC 2, Federación Internacional para el Procesamiento de la Información. - Oxford, Reino Unido: Springer Berlin Heidelberg Nueva York, Alemania, 2009. - Vol. 15-17 de julio, Editor de volumen WM Taha . — S. 385–409 . - ISBN 3-642-03033-5 , 978-3-642-03033-8 . — ISSN 0302-9743 .

Literatura

Tutoriales, guías, libros de referencia, uso

Historia, análisis, crítica

Enlaces