Pregunta

C++ es probablemente el lenguaje más popular para metaprogramación estática y Java no lo soporta.

¿Existen otros lenguajes además de C++ que admitan la programación generativa (programas que crean programas)?

¿Fue útil?

Solución

La alternativa a la metaprogramación de estilo de plantilla es el estilo Macro que se ve en varias implementaciones de Lisp.Yo sugeriría descargar Paul Graham's En ceceo y también echando un vistazo Clojure si está interesado en un Lisp con macros que se ejecute en la JVM.

Las macros en Lisp son mucho más poderosas que el estilo C/C++ y constituyen un lenguaje por derecho propio: están destinadas a la metaprogramación.

Otros consejos

déjame enumerar un algunos detalles importantes sobre cómo metaprogramación obras en ceceo (o esquema, o pizarra, o elige tu idioma "dinámico" favorito):

  • al hacer metaprogramación en lisp you no tienes que lidiar con dos idiomas.el código de nivel meta está escrito en el mismo lenguaje que el código de nivel de objeto que genera.La metaprogramación no se limita a dos niveles y también es más fácil para el cerebro.
  • en lisp tienes el compilador disponible en tiempo de ejecución.de hecho, la distinción entre tiempo de compilación y tiempo de ejecución parece muy artificial y depende en gran medida de dónde coloques tu punto de vista.en lisp con una simple llamada a función puedes compilar funciones en instrucciones de máquina que puedes usar a partir de ese momento como objetos de primera clase;es decir.pueden ser funciones sin nombre que puede mantener en una variable local o en una tabla hash global, etc.
  • macros en lisp son muy simples:un montón de funciones incluidas en una tabla hash y entregadas al compilador.para cada formulario que el compilador está a punto de compilar, consulta esa tabla hash.si encuentra una función, la llama en tiempo de compilación con el formulario original y, en lugar del formulario original, compila el formulario que devuelve esta función.(módulo algunos detalles no importantes) así que lisp macros son básicamente complementos para el compilador.
  • escribir una función lisp en lisp que evalúe el código lisp es de aproximadamente dos páginas de código (esto generalmente se llama evaluar).en dicha función tienes todo el poder para introducir cualquier regla nueva que desees en el nivel meta.(Sin embargo, hacer que funcione rápido requerirá algo de esfuerzo...casi lo mismo que iniciar un nuevo idioma...:)

ejemplos aleatorios de lo que puedes implementar como biblioteca de usuario usando metaprogramación lisp (estos son ejemplos reales de bibliotecas lisp comunes):

  • ampliar el idioma con continuaciones delimitadas (hu.dwim.delico)
  • implementar un js a lisp-rpc macro que puedes usar en javascript (que se genera a partir de lisp).se expande en una mezcla de código js/lisp que publica automáticamente (en la solicitud http) todas las variables locales a las que se hace referencia, las decodifica en el lado del servidor, ejecuta el cuerpo del código lisp en el servidor y devuelve el valor de retorno al javascript. lado.
  • agregue un prólogo como retroceso al lenguaje que se integra perfectamente con el código lisp "normal" (ver gritón)
  • un Extensión de plantillas XML al ceceo común (incluye un ejemplo de macros de lector que son complementos para el analizador lisp)
  • una tonelada de pequeños DSL, como bucle o iterar para un bucle fácil

La metaprogramación de plantillas es esencialmente un abuso del mecanismo de plantillas.Lo que quiero decir es que obtienes básicamente lo que esperarías de una característica que fue un efecto secundario no planificado: es un desastre y (aunque las herramientas están mejorando) un verdadero dolor de cabeza porque el lenguaje no apoyarlo para hacerlo (debo señalar que mi experiencia con lo último en esto está desactualizada, ya que esencialmente abandoné el enfoque.Sin embargo, no he oído hablar de ningún gran avance)

Jugar con esto alrededor del 98 fue lo que me impulsó a buscar mejores soluciones.Podría escribir sistemas útiles que dependieran de él, pero eran infernales.Husmear finalmente me llevó a Common Lisp.Claro, el mecanismo de la plantilla es Turing completo, pero también lo es el intercalado.

Common Lisp hace la metaprogramación "bien".Tienes todo el poder del lenguaje disponible mientras lo haces, sin sintaxis especial, y como el lenguaje es muy dinámico, puedes hacer más con él.

Por supuesto, hay otras opciones.Ningún otro lenguaje que he usado hace mejor la metaprogramación que Lisp, por eso lo uso para investigar código.Sin embargo, hay muchas razones por las que quizás quieras probar algo más, pero todo serán compensaciones.Puedes mirar Haskell/ML/OCaml, etc.Muchos lenguajes funcionales tienen algo parecido al poder de las macros Lisp.Puede encontrar algunas cosas dirigidas a .NET, pero todas son bastante marginales (en términos de base de usuarios, etc.).En realidad, ninguno de los grandes actores de los lenguajes utilizados industrialmente tiene algo así.

Nemerle y Abucheo son mis favoritos personales para este tipo de cosas.Nemerle tiene una sintaxis de macros muy elegante, a pesar de su mala documentación.La documentación de Boo es excelente pero sus macros son un poco menos elegantes.Sin embargo, ambos funcionan increíblemente bien.

Ambos apuntan a .NET, por lo que pueden interoperar fácilmente con C# y otros lenguajes .NET, incluso binarios de Java, si usa IKVM.

Editar:Para aclarar, me refiero a macros en el sentido Lisp de la palabra, no a las macros de preprocesador de C.Estos permiten la definición de nueva sintaxis y una metaprogramación pesada en tiempo de compilación.Por ejemplo, Nemerle viene con macros que validarán sus consultas SQL contra su servidor SQL en tiempo de compilación.

Nim es un lenguaje de programación relativamente nuevo que tiene un amplio soporte para metaprogramación estática y produce código compilado eficiente (similar a C++).

http://nim-lang.org/

Admite evaluación de funciones en tiempo de compilación, transformaciones de código AST tipo lisp a través de macros, reflexión en tiempo de compilación, tipos genéricos que se pueden parametrizar con valores arbitrarios y reescritura de términos que se pueden usar para crear tipos de alto nivel definidos por el usuario. optimizaciones de mirilla.Incluso es posible ejecutar programas externos durante el proceso de compilación que pueden influir en la generación del código.Como ejemplo, considere hablar con un servidor de base de datos que se ejecuta localmente para verificar que la definición ORM en su código (proporcionada a través de algún DSL) coincida con el esquema de la base de datos.

El Lenguaje de programación "D" Es similar a C++ pero tiene un soporte de metaprogramación mucho mejor.A continuación se muestra un ejemplo de un trazador de rayos escrito utilizando únicamente metaprogramación en tiempo de compilación:

traza

Además, hay una rama de gcc llamada "Concept GCC" que admite estructuras de metaprogramación que C++ no admite (al menos no todavía).

Concepto CCG

Common Lisp admite programas que escriben programas de varias maneras diferentes.

1) Los datos del programa y el "árbol de sintaxis abstracta" del programa son uniformes (¡expresiones S!)

2) defmacro

3) Macros del lector.

4) fregona

De estos, el verdadero alucinante es MOP.Lea "El arte del protocolo de metaobjetos". ¡Cambiará las cosas para ti, lo prometo!

recomiendo Haskell.Aquí hay un papel describiendo sus capacidades de metaprogramación en tiempo de compilación.

Mucho trabajo en Haskell:Lenguajes específicos de dominio (DSL), especificaciones ejecutables, transformación de programas, aplicación parcial, computación por etapas.Algunos enlaces para empezar:

La familia de lenguajes ML se diseñó específicamente para este propósito.Una de las historias de éxito más famosas de OCaml es la FFTW Biblioteca para FFT de alto rendimiento que es código C generado casi en su totalidad por un programa OCaml.

Saludos, Jon Harrop.

La mayoría de las personas intentan encontrar un lenguaje que tenga "reflexión final" para la autoinspección y algo así como "eval" para reificar un nuevo código.Tales idiomas son difíciles de encontrar (que Lisp es un contraejemplo principal) y ciertamente no son convencionales.

Pero otro enfoque es usar un conjunto de herramientas que puedan inspeccionar, generar y manipular el código del programa.Jackpot es una herramienta tan centrada en Java. http://jackpot.netbeans.org/

Nuestro kit de herramientas de reingeniería de software DMS es una herramienta, que funciona en C, C ++, C#, Java, COBOL, PHP, JavaScript, ADA, Verilog, VHDL y variedad de otros idiomas.(Utiliza los frontales de calidad de producción para permitirle leer todos estos Langauges).Mejor aún, puede hacer esto con varios idiomas al mismo instante.Ver http://www.semdesigns.com/Products/DMS/DMSToolkit.html

DMS tiene éxito porque proporciona un método regular y una infraestructura de soporte para un acceso completo a la estructura del programa como AST y, en la mayoría de los casos, a datos adicionales como tablas de símbolos, información de tipos, control y análisis de flujo de datos, todo lo necesario para realizar una manipulación sofisticada del programa.

'metaprogramación' es realmente un mal nombre para esta característica específica, al menos cuando se habla de más de un idioma, ya que esta característica solo es necesaria para una pequeña porción de idiomas que son:

  • estático
  • compilado en lenguaje de máquina
  • muy optimizado para el rendimiento en tiempo de compilación
  • extensible con tipos de datos definidos por el usuario (OOP en el caso de C++)
  • enormemente popular

elimine cualquiera de estos y la "metaprogramación estática" simplemente no tiene sentido.por lo tanto, me sorprendería si algún lenguaje remotamente convencional tuviera algo así, tal como se entiende en C++.

Por supuesto, los lenguajes dinámicos y varios lenguajes funcionales admiten conceptos totalmente diferentes que también podrían denominarse metaprogramación.

Lisp admite una forma de "metaprogramación", aunque no en el mismo sentido que la metaprogramación de plantillas de C++.Además, su término "estático" podría significar cosas diferentes en este contexto, pero Lisp también admite la escritura estática, si eso es lo que quiere decir.

El metalenguaje (ML), por supuesto: http://cs.anu.edu.au/student/comp8033/ml.html

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top