2012-07-12 11 views
7

es una plantilla de C++ ¿La metaprogramación es una forma de programación funcional? En caso afirmativo, ¿hay algunas dificultades, como el stackoverflow para la recurrencia sin cola relevante para la metaprogramación de plantillas de C++?es una plantilla de C++ La metaprogramación de una forma de programación funcional

Para el ejemplo de la plantilla factorial en this question, supongo que es una programación funcional estándar. ¿O la similitud es solo superficial?

#include <iostream> 
using namespace std; 

template< int n > 
struct factorial { enum { ret = factorial< n - 1 >::ret * n }; }; 

template<> 
struct factorial<0> { enum { ret = 1 }; }; 

int main() { 
    cout << "7! = " << factorial<7>::ret << endl; // 5040 
    return 0; 
} 
+5

Las plantillas C++ son en realidad un lenguaje de programación funcional extremadamente puro (¡sin efectos secundarios!), Con la particularidad de que se evalúan completamente en tiempo de compilación, a diferencia de la mayoría de los lenguajes funcionales. Y la sintaxis no es muy buena. Por lo tanto, tiene sentido que el mismo tipo de técnicas y algoritmos que funcionan con uno también se correlacionen con el otro. De hecho, existen proyectos que "desugar" un subconjunto de plantillas de Haskell a C++. No sé mucho sobre las características de rendimiento/"semántica operacional". – glaebhoerl

+1

Quizás debería consultar [boost :: phoenix] (http://www.boost.org/doc/libs/1_50_0/libs/spirit/phoenix/doc/html/index.html). –

+2

Esto es definitivamente una pregunta real. Es solo uno que es un poco abstruso. – Marcin

Respuesta

2

es C++ Plantilla ¿Metaprogramación de una forma de programación funcional?

¡Sí! La expansión de la plantilla no tiene efectos secundarios, por lo que es puramente funcional.

Si es así, haga algunas trampas como stackoverflow para recurrencia sin cola relevante para C++ ¿Metaprogramación de plantillas?

Absolutamente. Factorial no es una buena demostración de esto, ya que el resultado se desbordará mucho antes de que la pila lo haga, pero las recursiones largas definitivamente pueden causar el error del compilador. Curiosamente, sin embargo, los compiladores tienden a implementar plantillas de tal manera que obtienes la memorización automática. Por ejemplo, una implementación escrita ingenuamente de la serie Fibonacci tenderá a compilarse en el tiempo O (n) en lugar de O (2^n).

3

Creo que la mejor respuesta es que los dos conceptos son completamente diferentes. Sin embargo, eso no ayuda, así que aquí están algunos puntos clave que se me ocurre:

  • Ambas plantillas de C++ y (polimorfismo paramétrico) lenguajes funcionales como ML son ejemplos de generic programming y así que tiene algo de sentido mencionarlos juntos en una sola pregunta. En la academia, incluso hay Workshop on Generic Programming que a menudo cubre material de plantilla C++ y programación funcional al estilo ML.

  • Sin embargo, la metaprogramación de plantillas le proporciona una forma de escribir código que se "evalúa" durante la compilación de su código C++ y así puede usarlo solo para tareas bastante limitadas. Por otro lado, los programas funcionales normalmente se ejecutan, bueno, en tiempo de ejecución y puede definir estructuras de datos complejas, crear abstracciones, etc. (puede hacer algunas cosas utilizando la metaprogramación de plantillas, pero se verá feo).

  • ¿Por qué el ejemplo factorial es similar a los factoriales en la programación funcional? Cuando utiliza la metaprogramación de plantillas, no puede definir "variables mutables" (porque solo está definiendo nuevos tipos o plantillas) y, por lo tanto, la metaprogramación de plantillas puede parecerse un poco al estilo de programación funcional.

  • El código escrito mediante la metaprogramación de la plantilla se evalúa en tiempo de compilación. Esto significa que no puede depender de la entrada del usuario. Compila o no (el compilador puede tener alguna restricción sobre la profundidad de la recursión y renunciar después de un tiempo). Por otro lado, los programas funcionales pueden tomar algunas entradas y luego evaluarlas (lo que significa que pueden usar toda la pila o memoria disponible y luego fallar).

Para los programadores funcionales, sé que algunos lenguajes funcionales como Agda también pueden evaluar las cosas en tiempo de compilación, pero creo que es mejor mantener las cosas simples!

+16

Son * no * cosas completamente diferentes. Sería más cercano a la verdad decir que son lo mismo: la metaprogramación de plantillas C++ es la programación funcional. (Aunque lo contrario, por supuesto, no es cierto.) – glaebhoerl

+4

Los puntos clave contradicen su afirmación: la metaprogramación de plantillas de C++ y la programación funcional no son lo mismo, pero están muy cerca. De hecho, puede analizar un programa funcional en (un subconjunto de) Haskell, transformarlo e incluso ejecutarlo durante el tiempo de compilación en C++. P.ej. ver una biblioteca aquí http://abel.web.elte.hu/mpllibs/metaparse/index.html que puede hacerlo. –

+1

Ambos hacen algunos buenos puntos, pero aún diría que son cosas completamente diferentes en el _nivel alto_. En el nivel bajo, comparten algunos aspectos técnicos (como la metaprogramación de plantillas usa subconjuntos de estilo funcional), pero esa no es información realmente útil si se quiere considerar el panorama general. –

Cuestiones relacionadas