Creo que estás preguntando sobre dos cosas diferentes.
- La capacidad de un lenguaje de programación para representar todos sus programas como datos.
- Razonamiento sobre programas como datos.
Para fines analíticos, es útil mantenerlos separados. Me centraré en lo primero.
La capacidad de un lenguaje de programación para representar, manipular (y ejecutar) sus programas como los datos se conoce con términos tales como meta-programación o
homoiconicidad .
De una manera (incómoda), todos los lenguajes de programación conocidos pueden hacer metaprogramación, es decir, utilizando el tipo de datos de cadena junto con la capacidad de invocar programas externos (compilador, enlazador, etc.) en cadenas (por ejemplo, escribiéndolos en el archivo sistema primero). Sin embargo, eso probablemente no sea lo que quieres decir. Probablemente tenga una buena sintaxis en mente. Las cadenas no son una buena sintaxis para la representación de programas porque casi todas las cadenas no representan programas, es decir, el tipo de datos de cadena contiene mucha 'basura' cuando se ve como un mecanismo de representación de programas. Para empeorar las cosas, el álgebra de las operaciones de cadena no tiene esencialmente conexión con el álgebra de la construcción de programas.
Lo que probablemente tengas en mente es algo mucho más agradable. Por ejemplo, si es un programa, entonces es , pero como datos disponibles para la manipulación y el análisis. Esto a menudo se llama cita . En la práctica, la cita es inflexible, por lo que usamos cuasi cita en su lugar, que es una generalización de la cita donde la cita puede tener 'agujeros' en los que se pueden ejecutar programas que proporcionan datos para 'llenar' los agujeros. Por ejemplo es una cuasicita que representa un condicional donde en lugar de una condición tenemos un agujeroPAGP⟨ P⟩PAG[ ⋅ ] M ⟨ x > 0 ⟩ ⟨ i f
⟨ I f[ ⋅ ]t h e n7 7e l s e8 + 9 ⟩
[ ⋅ ] . Si el programa evalúa los datos , entonces la cuasi cita evalúa los datos
METRO⟨ X > 0 ⟩⟨ i f⟨ I f[ M]t h e n7 7e l s e8 + 9 ⟩
⟨ I fx > 0t h e n7 7e l s e8 + 9 ⟩ .
(Tenga en cuenta que es un programa normal (no un programa como datos) que devuelve un programa citado, es decir, un programa como datos). Para que esto funcione, necesita un tipo de datos para representar los programas. Típicamente, ese tipo de datos se llama AST (árbol de sintaxis abstracta), y puede ver (cuasi) comillas como mecanismos de abreviatura para AST.METRO
Varios lenguajes de programación ofrecen cuasicitas y otras características para la metaprogramación. Fue Lisp con su funcionalidad de macro que fue pionera en esta capacidad de tratar los programas como datos. Quizás desafortunadamente, el poder de las macros basadas en Lisp fue visto durante mucho tiempo para descansar en gran medida en la sintaxis minimalista de Lisp; No fue hasta MetaML (1) que se demostró que un lenguaje moderno y sintácticamente rico era capaz de metaprogramar. Desde entonces, MetaOCaml (2) (un descendiente de MetaML, importante por su avance en la búsqueda aún en curso para resolver el problema de cómo escribir programas como datos), Template Haskell (3) y Converge (4) (el primer idioma para obtener todas las características clave de metaprogramación en mi opinión) han demostrado que una variedad de lenguajes de programación modernos pueden albergar metaprogramación. Es importante darse cuenta de que podemos tomarcualquier lenguaje de programación y convertirlo en un lenguaje de
que sea junto con la capacidad de representar (y evaluar) sus propios programas como datos.L m p LLLm pL
La representación del resultado de la ejecución del programa, dada como datos, se logra agregando una función que toma un programa (dado como datos) como entrada y lo ejecuta , devolviendo su resultado. Por ejemplo, si es un programa que evalúa 17 y , la versión (cuasi-) citada de , es decir, como datos, entonces también devuelve 17. Hay toda clase de sutilezas aquí que estoy ignorando aquí, como la pregunta cuandoP ⟨ P ⟩ P P e v a l ( ⟨ P ⟩ ) P ⟨ P ⟩e v a l (⋅)PAG⟨ P⟩PAGPAGe v a l (⟨P⟩ )se están evaluando programas metaprogramados (dando lugar a la distinción entre metaprogramado en tiempo de compilación y en tiempo de ejecución), qué hacer con los tipos o evaluaciones fallidas, qué sucede con las variables enlazadas y libres en el proceso de pasar de a o viceversa.PAG⟨P⟩
En cuanto a la segunda dimensión, razonamiento sobre programas dados como datos. Tan pronto como pueda convertir los programas en datos, son datos "normales" y pueden razonarse como datos. Puede utilizar todo tipo de tecnología de prueba, por ejemplo, tipos dependientes o contratos o demostradores de teoremas interactivos o herramientas automatizadas, como Joshua ha señalado. Sin embargo, tendrá que representar la semántica de su idioma en el proceso de razonamiento. Si ese lenguaje, como lo requiere, tiene habilidades de metaprogramación, las cosas pueden volverse un poco complicadas y no se ha hecho mucho trabajo en esta dirección, siendo (5) la única lógica de programa para este propósito. También hay un trabajo basado en Curry-Howard sobre el razonamiento sobre metaprogramación (6, 7, 8). Tenga en cuenta que estos enfoques basados en la lógica, y el enfoque basado en el tipo (2) puede expresar propiedades que son válidas para todas las etapas futuras de metaprogramación. Aparte de (2) ninguno de esos documentos ha sido implementado.
En resumen: lo que solicitó se ha implementado, pero es bastante sutil y todavía hay preguntas abiertas, en particular sobre los tipos y el razonamiento simplificado.
W. Taha. Programación de etapas múltiples: su teoría y aplicaciones .
W. Taha y MF Nielsen. Clasificadores de entorno .
T. Sheard y S. Peyton Jones. Meta-programación de plantillas para Haskell .
L. Tratt. Meta-programación en tiempo de compilación en un lenguaje OO de tipo dinámico .
M. Berger, L. Tratt, Lógicas de programa para metaprogramación homogénea .
R. Davies, F. Pfenning, Un análisis modal de la computación por etapas .
R. Davies, Un enfoque de lógica temporal para el análisis del tiempo de enlace .
T. Tsukada, A. Igarashi. Una base lógica para los clasificadores de entorno .