stringtranslate.com

Metaprogramación

La metaprogramación es una técnica de programación en la que los programas de computadora tienen la capacidad de tratar otros programas como sus datos. Significa que un programa puede diseñarse para leer, generar, analizar o transformar otros programas, e incluso modificarse a sí mismo mientras se ejecuta. [1] [2] En algunos casos, esto permite a los programadores minimizar el número de líneas de código para expresar una solución, lo que a su vez reduce el tiempo de desarrollo. [3] También permite a los programas una mayor flexibilidad para manejar eficientemente nuevas situaciones sin tener que volver a compilar.

La metaprogramación se puede utilizar para mover cálculos del tiempo de ejecución al tiempo de compilación , para generar código utilizando cálculos en tiempo de compilación y para habilitar código que se modifica automáticamente . La capacidad de un lenguaje de programación para ser su propio metalenguaje se llama reflexión . [4] La reflexión es una característica valiosa del lenguaje para facilitar la metaprogramación.

La metaprogramación fue popular en las décadas de 1970 y 1980 utilizando lenguajes de procesamiento de listas como LISP . Las máquinas de hardware LISP fueron populares en la década de 1980 y permitieron aplicaciones que podían procesar código. Se utilizaban frecuentemente para aplicaciones de inteligencia artificial .

Enfoques

La metaprogramación permite a los desarrolladores escribir programas y desarrollar código que se ajuste al paradigma de programación genérica . Tener el propio lenguaje de programación como tipo de datos de primera clase (como en Lisp , Prolog , SNOBOL o Rebol ) también es muy útil; esto se conoce como homoiconicidad . La programación genérica invoca una función de metaprogramación dentro de un lenguaje al permitir escribir código sin la preocupación de especificar tipos de datos, ya que se pueden proporcionar como parámetros cuando se usan.

La metaprogramación suele funcionar de tres maneras. [5]

  1. El primer enfoque consiste en exponer los componentes internos del motor de ejecución al código de programación a través de interfaces de programación de aplicaciones (API) como la del emisor .NET IL .
  2. El segundo enfoque es la ejecución dinámica de expresiones que contienen comandos de programación, a menudo compuestos de cadenas, pero también pueden ser de otros métodos que utilizan argumentos o contexto, como JavaScript . [6] Por lo tanto, "los programas pueden escribir programas". Aunque ambos enfoques se pueden utilizar en el mismo idioma, la mayoría de los idiomas tienden a inclinarse hacia uno u otro.
  3. El tercer enfoque es salirse completamente del lenguaje. Los sistemas de transformación de programas de propósito general , como los compiladores, que aceptan descripciones de idiomas y llevan a cabo transformaciones arbitrarias en esos idiomas, son implementaciones directas de la metaprogramación general. Esto permite que la metaprogramación se aplique a prácticamente cualquier idioma de destino sin tener en cuenta si ese idioma de destino tiene capacidades de metaprogramación propias. Se puede ver esto en funcionamiento con Scheme y cómo permite abordar algunas limitaciones que enfrenta C mediante el uso de construcciones que eran parte del propio lenguaje Scheme para extender C. [7]

Lisp es probablemente el lenguaje por excelencia con posibilidades de metaprogramación, tanto por su precedencia histórica como por la simplicidad y el poder de su metaprogramación. En la metaprogramación Lisp, el operador sin comillas (normalmente una coma) introduce código que se evalúa en el momento de la definición del programa en lugar de en el tiempo de ejecución; consulte Formularios de autoevaluación y citas en Lisp . Por tanto, el lenguaje de metaprogramación es idéntico al lenguaje de programación anfitrión y las rutinas Lisp existentes se pueden reutilizar directamente para la metaprogramación, si se desea. Este enfoque se ha implementado en otros idiomas incorporando un intérprete en el programa, que trabaja directamente con los datos del programa. Existen implementaciones de este tipo para algunos lenguajes comunes de alto nivel, como RemObjects ' Pascal Script para Object Pascal .

Usos

Codigo de GENERACION

Un ejemplo simple de metaprograma es este script POSIX Shell , que es un ejemplo de programación generativa :

#!/bin/sh # metaprograma echo '#!/bin/sh' > programa para i en $( seq 992 ) haz echo "echo $i " >> programa terminado
chmod +x programa             

Este script (o programa) genera un nuevo programa de 993 líneas que imprime los números del 1 al 992. Esto es sólo una ilustración de cómo usar código para escribir más código; No es la forma más eficaz de imprimir una lista de números. No obstante, un programador puede escribir y ejecutar este metaprograma en menos de un minuto y habrá generado más de 1000 líneas de código en ese período de tiempo.

Un quine es un tipo especial de metaprograma que produce su propio código fuente como salida. Los quines generalmente tienen sólo un interés recreativo o teórico.

No toda la metaprogramación implica programación generativa. Si los programas se pueden modificar en tiempo de ejecución o si hay compilación incremental disponible (como en C# , Forth , Frink , Groovy , JavaScript , Lisp , Elixir , Lua , Nim , Perl , PHP , Python , REBOL , Ruby , Rust , SAS , Smalltalk , y Tcl ), entonces se pueden utilizar técnicas para realizar metaprogramación sin generar código fuente.

Un estilo de enfoque generativo es emplear lenguajes de dominio específico (DSL). Un ejemplo bastante común de uso de DSL implica la metaprogramación generativa: lex y yacc , dos herramientas utilizadas para generar analizadores y analizadores léxicos , permiten al usuario describir el lenguaje usando expresiones regulares y gramáticas libres de contexto , e incorporar los algoritmos complejos necesarios para analizar de manera eficiente el idioma.

Instrumentación de código

Un uso de la metaprogramación es instrumentar programas para realizar análisis dinámicos de programas .

Desafíos

Algunos argumentan que existe una curva de aprendizaje pronunciada para hacer un uso completo de las funciones de metaprogramación. [8] Dado que la metaprogramación brinda más flexibilidad y capacidad de configuración en tiempo de ejecución, el mal uso o el uso incorrecto de la metaprogramación puede resultar en errores injustificados e inesperados que pueden ser extremadamente difíciles de depurar para un desarrollador promedio. Puede introducir riesgos en el sistema y hacerlo más vulnerable si no se utiliza con cuidado. Algunos de los problemas comunes que pueden ocurrir debido al uso incorrecto de la metaprogramación son la incapacidad del compilador para identificar los parámetros de configuración faltantes, datos no válidos o incorrectos que pueden generar excepciones desconocidas o resultados diferentes. [9] Debido a esto, algunos creen [8] que solo los desarrolladores altamente capacitados deberían trabajar en el desarrollo de funciones que ejerciten la metaprogramación en un lenguaje o plataforma y los desarrolladores promedio deben aprender a usar estas funciones como parte de la convención.

Usos en lenguajes de programación.

Macrosistemas

Ensambladores de macros

IBM /360 y sus derivados tenían potentes funciones de macroensamblador que a menudo se usaban para generar programas completos en lenguaje ensamblador [ cita necesaria ] o secciones de programas (para diferentes sistemas operativos, por ejemplo). Las macros proporcionadas con el sistema de procesamiento de transacciones CICS tenían macros ensambladoras que generaban declaraciones COBOL como paso previo al procesamiento.

Otros ensambladores, como MASM , también admiten macros.

Metaclases

Las metaclases son proporcionadas por los siguientes lenguajes de programación:

Metaprogramación de plantillas

Metaprogramación por etapas

Tipos dependientes

El uso de tipos dependientes permite demostrar que el código generado nunca es inválido. [15] Sin embargo, este enfoque es de vanguardia y rara vez se encuentra fuera de los lenguajes de programación de investigación.

Implementaciones

La lista de sistemas de metaprogramación notables se mantiene en Lista de sistemas de transformación de programas .

Ver también

Referencias

  1. ^ Harald Sondergaard. «Curso de Análisis y Transformación de Programas» . Consultado el 18 de septiembre de 2014 .
  2. ^ Czarnecki, Krzysztof ; Eisenecker, Ulrich W. (2000). Programación Generativa . ISBN 0-201-30977-7.
  3. ^ Caminante, máximo. "El arte de la metaprogramación en Java". Nuevo Círculo . Consultado el 28 de enero de 2014 .
  4. ^ Krauss, Aarón. "Conceptos de programación: introspección y reflexión de tipos". La Societa . Consultado el 14 de septiembre de 2014 .
  5. ^ Joshi, Prateek (5 de abril de 2014). "¿Qué es la metaprogramación? - Parte 2/2". Enigma perpetuo . Consultado el 14 de agosto de 2014 .
  6. ^ por ejemplo, instancia_eval en Ruby toma una cadena o una función anónima. "Rdoc para clase: BasicObject (Ruby 1.9.3) - instancia_eval" . Consultado el 30 de diciembre de 2011 .
  7. ^ "El arte de la metaprogramación". IBM .
  8. ^ ab Disputas, Ian. "El desafío de la metaprogramación". IanBicking.org . Consultado el 21 de septiembre de 2016 .
  9. ^ Terry, Matt (21 de agosto de 2013). "Cuidado con la metaprogramación". Medio.com . Mediana Corporación . Consultado el 21 de agosto de 2014 .
  10. ^ A través del "Protocolo de metaobjetos" de Common Lisp Object System
  11. ^ "Metaprogramación de plantillas de C++". aszt.inf.elte.hu.Consultado el 23 de julio de 2022 .
  12. ^ Lisp (lenguaje de programación) "Formularios de autoevaluación y cotización", operador de cuasi cotización.
  13. ^ "LMS: generación de programas y compiladores integrados en Scala". scala-lms.github.io . Consultado el 6 de diciembre de 2017 .
  14. ^ Rompf, Tiark; Odersky, Martín (junio de 2012). "Puesta en escena modular liviana: un enfoque pragmático para la generación de código en tiempo de ejecución y DSL compilados". Comunitario. ACM . 55 (6): 121-130. doi :10.1145/2184319.2184345. ISSN  0001-0782. S2CID  52898203.
  15. ^ Chlipala, Adam (junio de 2010). "Ur: metaprogramación tipada estáticamente con cálculo de registros a nivel de tipo" (PDF) . Avisos ACM SIGPLAN . PLDI '10. 45 (6): 122-133. doi : 10.1145/1809028.1806612 . Consultado el 29 de agosto de 2012 .

enlaces externos