14

¿Cuál es exactamente la diferencia? Parece que los términos pueden ser empleados como sinónimos, pero la lectura de la entrada de Wikipedia para el Objetivo-c, me encontré con:Programación genérica v.s. Metaprogramación

Además del estilo de C de programación de procedimiento , C++ soporta directamente ciertas formas de objeto- programación orientada a , programación genérica y metaprogramación de .

en referencia a C++. ¿Entonces aparentemente son diferentes?

+0

Pregunta lingüística sin respuesta: v.s. o vs. - "v.s." versus "vs." :) –

+2

@Armen: eso también trae la pregunta: "v.s. vs. vs." vs. "v.s. v.s. vs."? – Claudiu

+3

@Claudiu: ¡Y que la sagrada recursión sea recurrente! : D –

Respuesta

12

La metaprogramación, en un sentido amplio, significa escribir programas que producen otros programas. P.ej. al igual que las plantillas en C++ producen código real solo cuando se crean instancias. Se puede interpretar una plantilla como un programa que toma un tipo como entrada y produce una función/clase real como salida. El preprocesador es otro tipo de metaprogramación. Otro ejemplo inventado de metaprogramación: un programa que lee un XML y produce algunos scripts SQL de acuerdo con el XML. De nuevo, en general, un metaprograma es un programa que produce otro programa, mientras que la programación genérica se trata de tipos parametrizados (generalmente con otros tipos) (incluidas las funciones).

editar después de considerar los comentarios a esta respuesta

+1

Sí, puede pensar en una plantilla como un metaprograma, pero usted realmente no puedo hacer lo mismo con, por ejemplo java generics. Entonces diría que la programación genérica se puede lograr usando la metaprogramación, pero esa no es la única manera. – sepp2k

+1

@ sepp2k: Bueno, especifiqué plantillas en C++. Pero estoy de acuerdo en que en otros lenguajes, la programación genérica no debe necesariamente implicar la metaprogramación –

+0

@ sepp2k: este es un buen punto que solo he implicado en mi respuesta también. IMO es un ejemplo incluso mejor que los genéricos de Java (que implican al menos alguna cooperación del compilador en el borrado de tipos) son funciones genéricas en Common Lisp, en las que el despacho se realiza puramente mediante inspección del tipo de tiempo de ejecución (IIRC, no soy Lisp experto, así que corrígeme si estoy equivocado). –

4

La programación genérica generalmente se refiere a funciones que pueden funcionar con muchos tipos. P.ej. una función de clasificación, que puede ordenar una colección de comparables en lugar de una función de clasificación para ordenar una matriz de entradas y otra para ordenar un vector de cadenas.

Metaprogramación se refiere a la inspección, la modificación o creación de clases, módulos o funciones mediante programación.

7

Yo definiría más o menos metaprogramming como "programas de escritura para escribir programas" y la programación genérica como "el uso de las características del lenguaje para escribir funciones, clases, etc. parametrizado en los tipos de datos de argumentos o miembros ".

Según esta norma, las plantillas de C++ son útiles tanto para la programación genérica (piensa vector, list, sort ...) y metaprogramming (pensemos por ejemplo, Boost y Espíritu). Además, yo argumentaría que la programación genérica en C++ (es decir, el polimorfismo en tiempo de compilación) se lleva a cabo mediante metaprogramación (es decir, generación de código a partir del código con plantilla).

4

Lo mejor es mirar a otros idiomas, ya que en C++, una única función es compatible con la programación genérica y Metaprogramación. (Las plantillas son muy potentes).

En el Esquema/Lisp, puede cambiar la gramática de su código. La gente probablemente conoce Scheme como "ese lenguaje de prefijo con muchos paréntesis", pero también tiene técnicas de metaprogramación muy poderosas (Macros Hygenic). En particular, try/catch puede ser creado , e incluso la gramática puede ser manipulado a un punto (Por ejemplo, aquí es un prefijo a INFIX convertidor si no desea escribir código de prefijo más: http://github.com/marcomaggi/nausicaa). Esto se logra a través de metaprogramación, código que escribe código que escribe código. Esto es útil para experimentar con nuevos paradigmas de programación (el operador AMB juega un papel importante en la programación no determinista. Espero que AMB se convierta en la corriente principal en los próximos 5 años más o menos ...)

En Java/C#, puede tener programación genérica a través de genéricos. Puede escribir una clase genérica que admita los tipos de muchas otras clases. Por ejemplo, en Java, puede usar Vector para crear un Vector de enteros. O vector si lo quieres específico para tu propia clase.

Donde las cosas se ponen raras, es que las plantillas C++ están diseñadas para programación genérica. Sin embargo, debido a algunos trucos, las plantillas de C++ son en sí mismas completas. Usando estos trucos, es posible agregar nuevas características al lenguaje C++ a través de meta-programación. Es complicado, pero funciona. Aquí hay un ejemplo que agrega despacho múltiple a C++ a través de plantillas. http://www.eptacom.net/pubblicazioni/pub_eng/mdisp.html. El ejemplo más típico es el de Fibonacci en tiempo de compilación: http://blog.emptycrate.com/node/271

32
  • Programación: Escribir un programa que crea, transforma, filtros, agregados y de otra manera manipula los datos.
  • Metaprogramación: escribir un programa que crea, transforma, filtra, agrega y manipula de otra forma los programas .
  • Programación genérica: escribir un programa que crea, transforma, filtra, agrega y manipula datos, pero hace solo los supuestos mínimos sobre la estructura de los datos, maximizando la reutilización en una amplia gama de tipos de datos.

Como ya se mencionó en varias otras respuestas, la distinción puede ser confusa en C++, ya que tanto la Programación genérica como la metaprogramación (estática/en tiempo de compilación) se realizan con plantillas. Para confundirte aún más, la programación genérica en C++ realmente usa la metaprogramación para ser eficiente, es decir, la especialización de plantillas genera programas especializados (rápidos) a partir de genéricos.

También tenga en cuenta que, como todo programador de Lisp sabe, el código y los datos son lo mismo, por lo que realmente no existe la "metaprogramación", todo es solo programación. De nuevo, esto es un poco difícil de ver en C++, ya que en realidad usa dos lenguajes de programación completamente diferentes para programación (C++, un lenguaje imperativo, procedimental, orientado a objetos en la familia C) y metaprogramación (Templates, un "accidente accidental" puramente funcional) "lenguaje en algún lugar entre el cálculo lambda puro y Haskell, con la sintaxis de extremo-feo, ya que nunca fue en realidad la intención de ser un lenguaje de programación.)

Muchos otros lenguajes que utilizan el mismo lenguaje de programación y metaprogramming (por ejemplo, Lisp, Plantilla Haskell, Converge, Smalltalk, Newspeak, Ruby, Ioke, Seph).

0

La programación genérica es una forma muy simple de metacodificación, aunque no suele ser el tiempo de ejecución. Es más como el preprocesador en C y se relaciona más con la programación de plantillas en la mayoría de los casos de uso y las implementaciones básicas.

Encontrará a menudo en los idiomas escritos que creará algunas implementaciones de algo donde solo el tipo es diferente. En lenguajes como Java esto puede ser especialmente doloroso ya que cada clase e interfaz define un nuevo tipo.

Puede generar esas clases convirtiéndolas en una cadena literal y luego reemplazando el nombre de la clase con una variable para interpolar.

Donde genéricos se usan en tiempo de ejecución es un poco diferente, en ese caso es simplemente programación variable, programación usando variables.

La forma de pensar que es simple, llevar a los archivos, compararlos y convertir cualquier cosa diferente en una variable. Ahora solo tiene un archivo reutilizable. Solo tiene que especificar qué es diferente, de ahí la variable de nombre.

Cómo se dieron los medicamentos genéricos que no todo se puede hacer variable como el tipo de variable que esperas o un tipo de yeso. A menudo habría una gran cantidad de duplicación de archivos donde lo único que era variable eran los tipos de variables. Esta fue una fuente muy común de duplicación. Aunque hay formas de evitarlo o mitigarlo, no son particularmente convenientes. Los genéricos han llegado como un tipo de variable variable para permitir que el tipo de variable sea variable. Debido a que el tipo de variable es algo que normalmente se expresa en el lenguaje de programación que ahora se puede especificar en tiempo de ejecución, también se considera metacodificación, aunque es un caso muy simple.

El efecto de no tener la variabilidad donde lo necesita es desenrollar sus variables, es decir que se ve forzado en lugar de tener una variable para hacer una implementación para cada posible valor variable.

Como se puede imaginar, es bastante caro. Esto sería muy común cuando se usa cualquier clase de biblioteca de almacenamiento de objetos de reutilización. Estos aceptarán cualquier objeto, pero en la mayoría de los casos las personas solo quieren lastimar un tipo de objdct. Si coloca un objeto de Tienda que amplía Objeto y luego desea recuperarlo, la firma del método en el objeto de almacenamiento devolverá simplemente Objeto, pero su código esperará un Objeto de Tienda. Esto romperá la compilación con la degradación del objeto a menos que lo vuelva a hacer para comprar. Esto plantea otro enigma ya que sin los genéricos no hay forma de verificar la compatibilidad y asegurarse de que el objeto que está almacenando sea una clase de Tienda.

Java evita la metaprogramación y trata de mantener el lenguaje simple usando los principios de polimorfismo OOP en lugar de hacer código flexible. Sin embargo, hay algunos problemas apremiantes y recurrentes que a través de la experiencia se han presentado y se abordan con la adición de instalaciones de metaprogramación mínima. Java no quiere ser un lenguaje de metaprogramación, pero importa moderadamente los conceptos de allí para resolver los problemas más molestos.

Los lenguajes de programación que ofrecen servicios de metacodificación pueden ser significativamente más productivos que los idiomas que evitarlo salvo en casos especiales, reflejos, polimorfismos OOP, etc. Sin embargo, a menudo también requiere mucha más habilidad y experiencia para generar inmanejables, mantenibles y código libre de errores. También suele haber una penalización de rendimiento para dichos lenguajes, ya que C++ es un poco raro porque está compilado en nativo.

Cuestiones relacionadas