¿Qué es exactamente la metaprogramación?


Estaba leyendo un artículo en el servidor sobre la programación ployglot en la plataforma Java. Algunos comentarios en el artículo se refieren a la metaprogramación como la capacidad de generar código (tal vez sobre la marcha).

Es metaprogramar la capacidad de generar código sobre la marcha o es la capacidad de inyectar métodos y atributos en objetos existentes en tiempo de ejecución (como lo que algunos lenguajes dinámicos como Python, Ruby y Groovy permiten).

Author: nbro, 2009-02-05

7 answers

La metaprogramación se refiere a una variedad de formas en que un programa tiene conocimiento de sí mismo o puede manipularse a sí mismo.

En lenguajes como C#, la reflexión es una forma de metaprogramación ya que el programa puede examinar información sobre sí mismo. Por ejemplo, devolver una lista de todas las propiedades de un objeto.

En lenguajes como ActionScript, puede evaluar funciones en tiempo de ejecución para crear nuevos programas como eval("x" + i).doSomething() afectaría a un objeto llamado x1 cuando i es 1 y x2 cuando yo tenga 2 años.

Finalmente, otra forma común de metaprogramación es cuando el programa puede cambiar a sí mismo en modas no triviales. LISP es bien conocido por esto y es algo que Paul Graham defendió hace una década. Tendré que buscar algunos de sus ensayos específicos. Pero la idea es que el programa cambiaría otra parte del programa basado en su estado. Esto permite un nivel de flexibilidad para tomar decisiones en tiempo de ejecución que es muy difícil en los idiomas más populares hoy.

También vale la pena señalar que en los buenos días de programación en ensamblaje directo, los programas que se alteraban a sí mismos en tiempo de ejecución eran necesarios y muy comunes.

Del ensayo de Paul Graham "Lo que hizo Diferente a Lisp":

Muchos idiomas tienen algo llamado macro. Pero las macros Lisp son únicas. Y lo creas o no, lo que hacen es relacionado con los paréntesis. El los diseñadores de Lisp no pusieron todos esos paréntesis en el lenguaje solo para ser diferente. Al programador de Blub, El código Lisp se ve raro. Pero esos los paréntesis están ahí por una razón. Son la evidencia externa de un diferencia fundamental entre Lisp y otros idiomas.

El código Lisp está hecho de datos Lisp objeto. Y no en el sentido trivial que los archivos de origen contienen caracteres, y cadenas son uno de los tipos de datos soportados por el idioma. Código Lisp, después de que es leído por el parser, está hecho de datos estructura que puedes atravesar.

Si entiende cómo funcionan los compiladores, lo que realmente está pasando no es tanto ese Lisp tiene una sintaxis extraña como esa Lisp no tiene sintaxis. Escribir programas en los árboles de análisis que se generan dentro del compilador cuando otros los idiomas se analizan. Pero estos analizan árboles son totalmente accesibles a su programa. Puedes escribir programas que manipúlalos. En Lisp, estos los programas se llaman macros. Son programas que escriben programa.

¿Programas que escriben programas? Cuando querríamos hacer eso? Ni muy a menudo, si piensas en Cobol. Todo la hora, si piensas en Ceceo. Se sería conveniente aquí si pudiera dar un ejemplo de una macro poderosa, y decir allí! ¿qué te parece? Pero si Lo hice, se vería como galimatías a alguien que no sabía Lisp; no hay espacio aquí para explicar todo lo que necesitas saber para entiende lo que significa. In Ansi Común Lisp Traté de mover cosas tan rápido como pude, y aun así No llegué a las macros hasta la página 160.

Pero creo que puedo dar una especie de argumento que podría ser convincente. El el código fuente del editor Viaweb fue probablemente alrededor del 20-25% de macros. Macro son más difíciles de escribir que el Lisp ordinario funciones, y se considera que es mal estilo para usarlos cuando no están necesario. Así que cada macro en ese código está ahí porque tiene que estar. Lo eso significa que es que al menos el 20-25% de el código en este programa está haciendo cosas que no puedes hacer fácilmente en cualquier otro idioma. Sin embargo escéptico el Blub programador podría ser sobre mi reclamaciones por los misteriosos poderes de Lisp, esto debería darle curiosidad. No estábamos escribiendo este código para nuestro diversión propia. Éramos una pequeña startup, programación tan duro como pudimos en para poner barreras técnicas entre nosotros y nuestros competidores.

Una persona sospechosa podría comenzar a preguntar si hubo alguna correlación aqui. Una gran parte de nuestro código hacer cosas que son muy difíciles de hacer en otros idiomas. El resultado el software hizo las cosas de nuestros competidores el software no podía hacer. Tal vez había algún tipo de conexión. Yo animo que sigas ese hilo. Puede sé más para ese viejo que anda cojeando en sus muletas de lo que parece.

 68
Author: DavGarcia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-12 12:31:56

Bueno, la metaprogramación es solo programación, pero es básicamente "escribir código que escribe código".

La habilidad que mencionas, cuando un programa puede observar y modificar su propia estructura y comportamiento se llama reflexión y es un tipo de metaprogramación.

Los lenguajes dinámicamente tipeados, tienen poderosas características de reflexión en tiempo de ejecución, hechas posibles por la naturaleza interpretada de estos lenguajes...

Los lenguajes tipeados estáticos también tienen una metaprogramación poderosa técnicas, por ejemplo la metaprogramación de la plantilla C++ ...

 24
Author: CMS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-05 05:33:25

Gran pregunta. Siento mucho ver que ninguna de las respuestas actualmente realmente responde a su pregunta correctamente. Tal vez pueda ayudar...

La definición de metaprogramación es realmente bastante simple: significa programas que manipulan programas.

Su respuesta aceptada dice programas que se manipulan a sí mismos. Esos son de hecho metaprogramas pero son un subconjunto de todos los metaprogramas.

Todos:

  • Analizadores
  • Idiomas específicos del dominio (DSLs)
  • Lenguajes específicos de dominio incrustados (EDSL)
  • Compiladores
  • Intérpretes
  • Reescritores de términos
  • Probadores de teoremas

Son metaprogramas. Así que el compilador de GCC es un metaprograma, el intérprete de CPython es un metaprograma, el sistema de álgebra computacional de Mathematica es un metaprograma, el probador del teorema de Coq es un metaprograma y así sucesivamente.

Otras respuestas han afirmado que los metaprogramas son programas que generan otros programas. Esos son de hecho metaprogramas pero, de nuevo, son un subconjunto de todos los metaprogramas. La biblioteca Transformada de Fourier más rápida en Occidente (FFTW) es un ejemplo de tal metaprograma. El código fuente está escrito principalmente en OCaml y genera bits de código C (llamados codelets) que se combinan para crear rutinas de alto rendimiento Transformada rápida de Fourier optimizadas para máquinas específicas. Esa biblioteca se utiliza realmente para proporcionar la Rutinas FFT en Matlab. La gente ha estado escribiendo programas para generar métodos numéricos durante décadas, desde los primeros días de FORTRAN .

El primer lenguaje de programación que integró soporte para metaprogramación fue el lenguaje de Procesador de listas (LISP) a finales de la década de 1950. LISP 1.5 incluyó una serie de características que hicieron la metaprogramación más fácil. En primer lugar, el tipo de datos principales de LISP son listas anidadas, es decir, árboles como (a (b c) d), lo que significa que cualquier código LISP puede expresarse de forma nativa como un dato estructura. Esto se conoce como homoiconicidad. En segundo lugar, el código LISP se puede convertir en datos fácilmente usando QUOTE. Por ejemplo (+ 1 2 3) añade 1+2+3 y (QUOTE (+ 1 2 3)) crea una expresión que añade 1+2+3 cuando se evalúa. En tercer lugar, LISP proporcionó un evaluador meta-circular que le permite usar el intérprete o compilador host para evaluar el código LISP en tiempo de ejecución, incluido el código LISP generado en tiempo de ejecución. Los descendientes de LISP incluyenScheme yClojure . En todos estos idiomas la metaprogramación es más comúnmente visto en forma de programas que se modifican a sí mismos, típicamente usando macros.

En la década de 1970, Robin Milner desarrolló unMetaLanguage (ML) que evolucionó en la familia ML de lenguajes de programación que incluyeEstándar ML yOCaml y fuertemente influenciadoHaskell yF#. Estos idiomas facilitan la expresión de otros idiomas. En estos idiomas, los metaprogramas se ven más comúnmente en forma de lexers, analizadores, intérpretes y compiladores.

En 1994, Erwin Unruh descubrió que el sistema de plantillas C++ estaba completo y podía ser utilizado para ejecutar programas arbitrarios en tiempo de compilación. La metaprogramación de plantillas de C++ trajo la metaprogramación a las masas sin lavar que (ab) la usó para muchas cosas diferentes, incluida la generación de métodos numéricos en la biblioteca Blitz++ .

 23
Author: Jon Harrop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-14 07:59:25

Esta es solo mi opinión personal, que es probablemente la definición más liberal de metaprogramación.

Creo que incluye:

  1. Generación de código de compilación o generación de código de tiempo de ejecución (o ambas)
  2. Pensamiento Orientado a Aspectos o Programación Orientada a Aspectos
  3. SECO Pensando

Creo que puedes llegar allí usando cualquiera de estos y en combinación:

  1. Reflexión
  2. DSLs (Lenguajes Específicos de Dominio)
  3. Atributos (. NET) o Anotaciones (Java)
  4. Genéricos (. NET/Java)
  5. Plantillas (C++)
  6. method_missing (Ruby)
  7. cierres / funciones de primera clase / delegados
  8. Programación Orientada al Aspecto AOP
 8
Author: BuddyJoe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-23 02:37:41

La metaprogramación es escribir un programa que produce otro programa. Esto es algo en lo que los idiomas como Lisp son muy buenos. Es mucho más fácil hacerlo en un lenguaje que soporta macros reales (no macros de C++, sino más bien aquellas que pueden manipular el código que generan)como Ruby, Lisp, Scheme, etc. que en un lenguaje como Java.

Una implementación es crear un "lenguaje específico de dominio" que es una forma de mejorar un lenguaje de programación para lograr una tarea específica. Puede ser increíblemente poderoso si se hace correctamente. Ruby on Rails es un buen ejemplo de este tipo de programación.

Si está interesado en explorar este método, eche un vistazo a Estructura e Interpretación de Programas de Computadora que es uno de los libros seminales que cubren el tema.

 5
Author: Steve Rowe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-05 05:27:47

La metaprogramación es la escritura de programas de computadora que escriben o manipulan otros programas (o ellos mismos) como sus datos, o que hacen parte del trabajo en tiempo de ejecución que de otra manera se haría en tiempo de compilación. En muchos casos, esto permite a los programadores hacer más en la misma cantidad de tiempo que tomarían para escribir todo el código manualmente, o da a los programas una mayor flexibilidad para manejar de manera eficiente nuevas situaciones sin recompilación. (Fuente.)

Básicamente, es escribir código que produce más código, que se ejecuta para lograr algún objetivo. Esto generalmente se hace dentro del mismo lenguaje (usando javascript para crear una cadena javascript, luego eval) o para emitir otro lenguaje (usando.NET para crear un archivo por lotes de windows).

 4
Author: EndangeredMassa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-05 05:21:30

Wikipedia tiene un buen artículo sobre el tema. Uno no tiene que hacer modificaciones de tiempo de ejecución para que algo califique como metaprogramación. Por ejemplo, muchas personas usan plantillas de C++ para hacer metaprogramación en tiempo de compilación.

 3
Author: Mr Fooz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-05 05:21:30