Articulo de referencia

evaluador metacircular

En informática , un evaluador metacircular ( MCE ) o intérprete metacircular ( MCI ) es un intérprete que define cada característica del lenguaje interpretado utilizando una fun...

En informática , un evaluador metacircular ( MCE ) o intérprete metacircular ( MCI ) es un intérprete que define cada característica del lenguaje interpretado utilizando una funcionalidad similar del lenguaje anfitrión del intérprete. Por ejemplo, la interpretación de una aplicación lambda puede implementarse mediante la aplicación de funciones. [ 1 ] La evaluación metacircular es más prominente en el contexto de Lisp . [ 1 ] [ 2 ] Un autointérprete es un intérprete metacircular donde el lenguaje interpretado es casi idéntico al lenguaje anfitrión; ambos términos se utilizan a menudo como sinónimos. [ 3 ]

Historia

La disertación de Corrado Böhm [ 4 ] describe el diseño de un compilador autoalojado . [ 5 ] Debido a la dificultad de compilar funciones de orden superior , muchos lenguajes se definieron mediante intérpretes, siendo Lisp el más destacado. [ 1 ] [ 6 ] El término en sí fue acuñado por John C. Reynolds , [ 1 ] y popularizado a través de su uso en el libro Estructura e interpretación de programas informáticos . [ 3 ] [ 7 ]

Autointérpretes

Un autointérprete es un intérprete metacircular donde la lengua anfitriona es también la lengua que se interpreta. [ 8 ] Un autointérprete muestra una función universal para la lengua en cuestión y puede ser útil para aprender ciertos aspectos de la misma. [ 2 ] Un autointérprete proporcionará una definición circular y vacía de la mayoría de las construcciones lingüísticas y, por lo tanto, ofrece poca información sobre la semántica de la lengua interpretada, por ejemplo, la estrategia de evaluación . Abordar estos problemas produce la noción más general de un "intérprete definicional". [ 1 ]

De autointérprete a máquina abstracta

Esta parte se basa en la Sección 3.2.4 de la tesis de Danvy. [ 9 ]

Aquí está el núcleo de un autoevaluador para elλ{\displaystyle \lambda }cálculo. La sintaxis abstracta delλ{\displaystyle \lambda }El cálculo se implementa de la siguiente manera en OCaml , representando las variables con su índice de De Bruijn , es decir, con su desplazamiento léxico (que comienza en 0):

término de tipo = IND de int (* índice de Bruijn *) | ABS de plazo | APP de término * término

El evaluador utiliza un entorno:

tipo valor = FUN de ( valor -> valor )let rec eval ( t : term ) ( e : value list ) : value = match t with IND n -> List . nth e n | ABS t' -> FUN ( fun v -> eval t' ( v :: e )) | APP ( t0 , t1 ) -> apply ( eval t0 e ) ( eval t1 e ) and apply ( FUN f : value ) ( a : value ) = f alet main ( t : term ) : value = eval t []

Los valores (de tipo value) combinan valores expresables (el resultado de evaluar una expresión en un entorno) y valores denotables (los valores denotados por variables en el entorno), una terminología que se debe a Christopher Strachey . [ 10 ] [ 11 ]

Los entornos se representan como listas de valores denotables.

El evaluador principal tiene tres cláusulas:

  • Asigna una variable (representada con un índice de De Bruijn) al valor del entorno actual en dicho índice.
  • Este proceso asigna una función sintáctica a una función semántica. (Aplicar una función semántica a un argumento se reduce a evaluar el cuerpo de la función sintáctica correspondiente en su entorno léxico, ampliado con el argumento).
  • Convierte una aplicación sintáctica en una aplicación semántica.

Este evaluador es compositivo, ya que cada una de sus llamadas recursivas se realiza sobre una subparte propia del término dado. Además, es de orden superior, puesto que el dominio de valores es un espacio de funciones.

En "Intérpretes Definicionales", Reynolds respondió a la pregunta de si un auto-intérprete de este tipo está bien definido. Su respuesta fue negativa, ya que la estrategia de evaluación del lenguaje definido (el lenguaje fuente) está determinada por la estrategia de evaluación del lenguaje definitorio (el metalenguaje). Si el metalenguaje sigue el principio de paso por valor (como OCaml), el lenguaje fuente también lo sigue. Si el metalenguaje sigue el principio de paso por nombre (como Algol 60 ), el lenguaje fuente igualmente lo sigue. Y si el metalenguaje sigue el principio de paso por necesidad (como Haskell ), el lenguaje fuente igualmente lo sigue.

En "Intérpretes Definicionales", Reynolds definió con precisión un auto-intérprete al hacerlo independiente de la estrategia de evaluación de su lenguaje definitorio. Fijó la estrategia de evaluación transformando el auto-intérprete en un estilo de paso de continuaciones , que es independiente de la estrategia de evaluación, como se recoge posteriormente en los Teoremas de Independencia de Gordon Plotkin . [ 12 ]

Además, debido a que aún no se habían descubierto las relaciones lógicas , Reynolds hizo que el evaluador resultante que pasa la continuación fuera de primer orden mediante (1) la conversión a cierre y (2) la desfuncionalización de la continuación.

Señaló la «cualidad de máquina» del intérprete resultante, que es el origen de la máquina CEK ya que la transformación CPS de Reynolds era para llamada por valor. [ 13 ] Para llamada por nombre, estas transformaciones mapean el auto-intérprete a una instancia temprana de la máquina de Krivine . [ 14 ] La máquina SECD y muchas otras máquinas abstractas pueden derivarse entre sí de esta manera. [ 15 ] [ 16 ]

Es notable que las tres máquinas abstractas más famosas para laλ{\displaystyle \lambda }El cálculo se corresponde funcionalmente con el mismo autointérprete.

Autointerpretación en lenguajes de programación completos

Los lenguajes de programación totalmente funcionales que son fuertemente normalizadores no pueden ser Turing completos , de lo contrario se podría resolver el problema de la parada comprobando si el programa cumple con la verificación de tipos. Esto significa que hay funciones computables que no se pueden definir en el lenguaje total. [ 17 ] En particular, es imposible definir un autointérprete en un lenguaje de programación total, por ejemplo, en cualquiera de los cálculos lambda tipados , como el cálculo lambda simplemente tipado , el Sistema F de Jean-Yves Girard o el cálculo de construcciones de Thierry Coquand . [ 18 ] [ 19 ] Aquí, por "autointérprete" entendemos un programa que toma una representación de un término fuente en algún formato simple (como una cadena de caracteres) y devuelve una representación del término normalizado correspondiente. Este resultado de imposibilidad no se cumple para otras definiciones de "autointérprete". Por ejemplo, algunos autores se han referido a funciones de tipoπττ{\displaystyle \pi \,\tau \to \tau }como autointérpretes, dondeπτ{\displaystyle \pi \,\tau }es el tipo de representaciones deτ{\displaystyle \tau }términos tipificados. Para evitar confusiones, nos referiremos a estas funciones como autorreconocedores . Brown y Palsberg demostraron que los autorreconocedores podían definirse en varios lenguajes fuertemente normalizadores, incluidos el Sistema F y el Sistema F ω . [ 20 ] Esto resultó ser posible porque los tipos de términos codificados que se reflejan en los tipos de sus representaciones impiden la construcción de un argumento diagonal . En su artículo, Brown y Palsberg afirman refutar la "sabiduría convencional" de que la autointerpretación es imposible (y se refieren a Wikipedia como un ejemplo de la sabiduría convencional), pero lo que realmente refutan es la imposibilidad de los autorreconocedores, un concepto distinto. En su trabajo posterior, cambian a la terminología más específica de "autorreconocedor" utilizada aquí, distinguiéndolos notablemente de los "autoevaluadores", de tipoπτπτ{\displaystyle \pi \,\tau \to \pi \,\tau }. [ 21 ] También reconocen que implementar la autoevaluación parece más difícil que el autorreconocimiento, y dejan la implementación de la primera en un lenguaje fuertemente normalizador como un problema abierto.

Usos

En combinación con una implementación de lenguaje existente, los intérpretes metacirculares proporcionan un sistema base a partir del cual extender un lenguaje, ya sea hacia arriba añadiendo más características o hacia abajo eliminando características mediante la compilación en lugar de interpretarlas. [ 22 ] También son útiles para escribir herramientas estrechamente integradas con el lenguaje de programación, como depuradores sofisticados. Un lenguaje diseñado teniendo en cuenta una implementación metacircular suele ser más adecuado para construir lenguajes en general, incluso lenguajes completamente diferentes del lenguaje anfitrión.

Ejemplos

Muchos lenguajes tienen una o más implementaciones metacirculares. A continuación se muestra una lista parcial.

Algunos lenguajes con una implementación metacircular diseñada de abajo hacia arriba, agrupados en orden cronológico:

Algunos lenguajes con implementación metacircular a través de terceros:

Véase también

Referencias

  1. 1 2 3 4 5 Reynolds, John C. (1972). "Intérpretes definicionales para lenguajes de programación de orden superior". Actas de la conferencia anual de la ACM sobre - ACM '72 (PDF) . Vol.  2. Actas de la 25.ª Conferencia Nacional de la ACM. págs. 717–740 . doi : 10.1145/800194.805852 . Recuperado el 14 de abril de 2017 . 
  2. 1 2 Reynolds, John C. (1998). "Intérpretes definicionales revisados" (PDF) . Higher-Order and Symbolic Computation . 11 (4): 355– 361. doi : 10.1023/A:1010075320153 . S2CID 34126862. Recuperado el 21 de marzo de 2023 . 
  3. 1 2 Abelson, Harold ; Sussman, Gerald ; Sussman, Julie (1996) [Publicado por primera vez en 1984 (1.ª ed.)]. "El evaluador metacircular" . Estructura e interpretación de programas informáticos . MIT. Archivado del original el 29 de abril de 2024. Recuperado el 3 de enero de 2025 .
  4. ^ Böhm, Corrado (1954). "Calculatrices digitales. Du déchiffrage des formules logico-mathématiques par la machine même dans la conception du program". Ana. Estera. Pura Appl . 4 (37): 1-51 .
  5. Knuth, Donald E. ; Pardo, Luis Trabb (agosto de 1976). El desarrollo temprano de los lenguajes de programación . pág. 36. 
  6. McCarthy, John (1961). "Una función LISP universal" (PDF) . Manual del programador de Lisp 1.5 . pág. 10. 
  7. Harvey, Brian. "Por qué la estructura y la interpretación de los programas informáticos son importantes" . people.eecs.berkeley.edu . Consultado el 14 de abril de 2017 .
  8. Braithwaite, Reginald (22 de noviembre de 2006). "La importancia del intérprete metacircular" . Recuperado el 22 de enero de 2011 .
  9. Danvy, Olivier (2006). Un enfoque analítico de los programas como objetos de datos (Tesis). doi : 10.7146/aul.214.152 . ISBN 9788775073948.
  10. Strachey , Christopher (1967). Conceptos fundamentales en lenguajes de programación (Informe técnico). doi : 10.1023/A:1010000313106 .
  11. Mosses, Peter D. (2000). "Prólogo a 'Conceptos fundamentales en lenguajes de programación'"". Computación de orden superior y simbólica . 13 (1/2): 7– 9. doi : 10.1023/A:1010048229036 . S2CID 39258759 . 
  12. Plotkin, Gordon D. (1975). "Llamada por nombre, llamada por valor y el cálculo lambda" . Theoretical Computer Science . 1 (2): 125– 159. doi : 10.1016/0304-3975(75)90017-1 .
  13. Felleisen, Matthias ; Friedman, Daniel (1986). Operadores de control, la máquina SECD y el cálculo lambda (PDF) . Descripción formal de conceptos de programación III, Elsevier Science Publishers BV (North-Holland). págs. 193–217 . 
  14. Schmidt, David A. (1980). "Máquinas de transición de estados para expresiones de cálculo lambda". Máquinas de transición de estados para expresiones de cálculo lambda . Lecture Notes in Computer Science. Vol. 94. Generación de compiladores dirigida por semántica, LNCS 94. págs. 415–440 . doi : 10.1007/3-540-10250-7_32 . ISBN   978-3-540-10250-2.
  15. Danvy , Olivier (2004). Una deconstrucción racional de la máquina SECD de Landin (PDF) . Implementación y aplicación de lenguajes funcionales, 16.º Taller Internacional, IFL 2004, Artículos seleccionados revisados, Lecture Notes in Computer Science 3474, Springer. pp. 52–71 . ISSN 0909-0878 .  
  16. Ager, Mads Sig; Biernacki, Dariusz; Danvy, Olivier ; Midtgaard, Jan (2003). "Una correspondencia funcional entre evaluadores y máquinas abstractas" . BRICS Report Series . 10 (13). 5.ª Conferencia Internacional ACM SIGPLAN sobre Principios y Práctica de la Programación Declarativa (PPDP'03): 8–19 . doi : 10.7146/brics.v10i13.21783 .
  17. Riolo, Rick; Worzel, William P.; Kotanchek, Mark (4 de junio de 2015). Teoría y práctica de la programación genética XII . Springer. pág. 59. ISBN  978-3-319-16030-6. Consultado el 8 de septiembre de 2021 .
  18. Conor McBride (mayo de 2003), "sobre la rescisión del contrato" (publicado en la lista de correo Haskell-Cafe).
  19. Andrej Bauer (junio de 2014), Respuesta a: Un lenguaje total que solo un lenguaje Turing completo puede interpretar (publicado en el sitio StackExchange de Ciencias de la Computación Teórica)
  20. Brown, Matt; Palsberg, Jens (11 de enero de 2016). «Rompiendo la barrera de la normalización: Un auto-intérprete para f-omega» (PDF) . Actas del 43.º Simposio Anual ACM SIGPLAN-SIGACT sobre Principios de Lenguajes de Programación . págs. 5-17 . doi : 10.1145/2837614.2837623 . ISBN  9781450335492. S2CID 14781370 . 
  21. Brown, Matt; Palsberg, Jens (enero de 2017). «Autoevaluación tipada mediante funciones de tipo intensionales». Actas del 44.º Simposio ACM SIGPLAN sobre Principios de Lenguajes de Programación . págs. 415–428 . doi : 10.1145/3009837.3009853 . ISBN  9781450346603.
  22. Oriol, Manuel; Meyer, Bertrand (29 de junio de 2009). Objetos, componentes, modelos y patrones: 47.ª Conferencia Internacional, TOOLS EUROPE 2009, Zúrich, Suiza, 29 de junio - 3 de julio de 2009, Actas . Springer Science & Business Media. pág. 330. ISBN  9783642025716Consultado el 14 de abril de 2017 .
  23. Implementación metacircular del lenguaje de programación Pico
  • Estructura e interpretación de programas informáticos (SICP) , versión en línea del libro completo, consultado el 18 de enero de 2009.
  • Metascala