2010-04-19 13 views
20

Paul Graham escribió que "The unusual thing about Lisp-- in fact, the defining quality of Lisp-- is that it can be written in itself." Pero eso no me parece para nada inusual o definitivo.¿Qué significa que "Lisp se puede escribir en sí mismo?"

ISTM que un lenguaje de programación se define por dos cosas: su compilador o intérprete, que define la sintaxis y la semántica para el lenguaje por fiat, y su biblioteca estándar, que define en gran medida las expresiones idiomáticas y técnicas los usuarios utilizarán al escribir código en el idioma.

Con algunas excepciones específicas, (los miembros que no pertenecen a C# de la familia .NET, por ejemplo) las bibliotecas estándar de la mayoría de los idiomas están escritas en ese idioma por dos muy buenas razones: porque compartirá el mismo conjunto de definiciones sintácticas, convenciones de llamadas a funciones, y el "aspecto y comportamiento" general del lenguaje, y porque las personas que es probable que escriban una biblioteca estándar para un lenguaje de programación son sus usuarios, y en particular su (s) diseñador (es). Entonces no hay nada único allí; eso es bastante estándar.

Y una vez más, no hay nada único o inusual en el compilador de un lenguaje escrito en sí mismo. Los compiladores C están escritos en C. Los compiladores de Pascal están escritos en Pascal. El compilador de C# de Mono está escrito en C#. Diablos, incluso some scripting languages tienen implementaciones "escritas en sí mismas".

Entonces, ¿qué significa que Lisp es inusual en ser escrito en sí mismo?

+6

Como dices, un compilador o intérprete autohospedado no es una gran noticia. Un lenguaje cuyo árbol sintáctico abstracto * es * el código, que en sí mismo es totalmente manipulable como datos, por el contrario, es más bien un animal diferente. Escaneando el artículo de McCarthy sobre el cual estaba comentando Paul Graham, no hay ninguna duda razonable de que sea esta simetría la que tenga importancia. –

+2

http://stackoverflow.com/questions/1481053/what-is-the-exact-definition-of-a-metacircular-interpreter –

Respuesta

10

Probablemente lo que Pablo quiere decir es que la representación de Lisp sintaxis como un valor Lisp ha sido estandarizada y penetrante. Es decir, un programa Lisp es simplemente un tipo especial de expresión S, y es excepcionalmente fácil escribir el código Lisp que manipula el código Lisp. Escribir un intérprete Lisp en Lisp es un caso especial, y no es tan emocionante como la capacidad general de tener una representación unificada para el código y los datos.

+6

Lo que usted describe es la propiedad del idioma siendo [homoiconic] (http: // en .wikipedia.org/wiki/Homoiconic), que es un rasgo compartido por otros idiomas también. –

+0

@Greg: Siempre tuve un punto débil para TRAC (y su sucesor, MINT), pero mi sensación es que esos programadores nunca se han aprovechado de la homoiconicidad en la forma en que los programadores Lisp ... –

+3

Nunca puedo leer la palabra Homoicónico sin pensar en Judy Garland. –

7

Bueno, el enlace que proporcionó continúa diciendo que, si continúa leyendo, responderá su pregunta en detalle.

Lo curioso Lisp-- en hecho, la calidad de la definición Lisp-- es que se puede escribir en sí mismo. Para entender lo que McCarthy quiso decir con esto, vamos a volver sobre sus pasos , con su notación matemática traducida al código Common Lisp .

+2

Sí, y luego el artículo termina. –

+0

@Mason: puede descargar el archivo PostScript, convertirlo a PDF aquí: http://www.ps2pdf.com/convert.htm, y leerlo con Adobe Reader. Tiene alrededor de trece páginas. –

+1

Hay un enlace al artículo completo en la siguiente línea ... – harto

7

Acabo de eliminar una respuesta muy larga que probablemente sea inapropiada aquí.

Sin embargo considerar que:

  1. LISP no tiene "sintaxis" si usted quiere decir con el significado que tiene para lenguajes como C/Java/Pascal ... hay un (inicial, pero personalizable) sintaxis para el lector Common LISP, pero eso es una cosa diferente (LISP que Graham está hablando no es Common Lisp, y una (la) lector es no el lenguaje LISP, pero sólo un procedimiento). Algo como "(lambda (x) (* x 2))" es no código LISP, pero texto que, por ejemplo, el lector estándar CL puede convertir a código LISP.

  2. LISP no sólo puede ser escrito en LISP (si se refiere a la capacidad de "arrancar") pero de hecho se hizo a la existencia de esa manera. La primera implementación de eval a finales de 1950 se escribió en LISP en papel, y luego se convirtió manualmente en el lenguaje de máquina (1): LISP comenzó como una idea puramente teórica no destinada a ser implementada. No conozco ningún otro lenguaje de computadora que siguiera el de esa ruta. Por ejemplo, C++ se concibió como un preprocesador para un compilador de C y se escribió en C, no fue un programa C++ convertido posteriormente en C para ser capaz de ejecutarlo.

Hay muchos otros aspectos en los que Lisp es bastante diferente, y creo que la mejor manera de tener una idea de que es para aplicar en la práctica un intérprete de LISP juguete (que es un trabajo más pequeño de lo que cabría piense especialmente si su "lenguaje de máquina" es un lenguaje de alto nivel con tipado dinámico como Python).

(1) en http://www-formal.stanford.edu/jmc/history/lisp/node3.html puede encontrar cómo McCarthy describe que eval[e, a] se encontró en el papel por primera vez como un resultado teórico interesante (una "función universal" más ordenado la ejecución de una máquina universal de Turing) cuando sólo las estructuras de datos y funciones nativas elementales había sido diseñado para el lenguaje Lisp que el grupo estaba construyendo. Esta función manuscrita fue implementada a mano por S.R. Russell en código máquina y comenzó a servirlos como el primer intérprete de Lisp.

+0

¿Dónde puedo encontrar que "la primera implementación de eval a fines de la década de 1950 [que] fue escrita en LISP en papel" –

+0

@ RenéG: ver la respuesta editada, agregué una referencia. – 6502

6

No está diciendo que Lisp se pueda usar para escribir un compilador Lisp. Él está diciendo que el lenguaje se compone de sus propias estructuras de datos. Entonces, si bien no puede crear una función C a partir de estructuras de datos C, puede hacerlo en Lisp. Un programa se compone de listas que ejecuta su computadora, y el efecto de esas listas puede ser crear otras listas que luego se ejecutan, y el efecto de esas listas puede ser crear más listas para ser ejecutadas. C no tiene esta propiedad. El código C no puede, por ejemplo, manipular su propio AST.

+1

El código C puede manipularse. En realidad, creo que el Código de auto modificación fue bastante popular por un tiempo. – Ponkadoodle

+5

@wallacoloo: Aquí hay una distinción sutil entre el * idioma * y la * implementación *. El código C no puede manipular ** en sí **, pero puede manipular el código del ** lenguaje de máquina ** en el que está implementado. Ese es un nivel de abstracción completamente diferente de la manipulación del código Lisp en Lisp. –

+0

Oh, la palabra clave era AST, que es una edición o algo que eché de menos. Perdón, y gracias por la aclaración. – Ponkadoodle

4

La idea principal es que el lenguaje Lisp tiene un núcleo muy pequeño de unas pocas funciones y el mecanismo de evaluación principal se puede anotar en código en una sola página.

Ese es el núcleo de Lisp.

Para comprender el funcionamiento básico de la lengua sólo es necesario tener en cuenta que la única página de código: se explica el funcionamiento de las variables, cómo llamar a la función de las obras, cómo las nuevas funciones se pueden crear, etc.

Justo piense en cuánto puede eliminar de una implementación de idioma para llegar a lo básico. ¿Cuál es el conjunto mínimo de primitivas y cuál es el motor de ejecución mínimo? Para escribir un Lisp en un Lisp te bajas a casi nada.

Si observa una implementación PASCAL (como ejemplo), no se implementa en PASCAL, sino en PASCAL + una cantidad mayor de código que proporciona las estructuras de datos necesarias para representar entidades de lenguaje, un analizador, un compilador, un tiempo de ejecución, ... - fuera de la caja PASCAL no ofrece mucho - uno tiene que construir estos (o utilizar una biblioteca).

Wirth (el creador de Pascal) ha escrito un libro que explica la implementación de un lenguaje muy pequeño parecido a Pascal; aún debe escribir código sustancial para implementar ese lenguaje: analizador, generador de código, tiempo de ejecución, cargador. ..

Por el contrario, en un Lisp, el código fuente Lisp tiene una representación natural y la rutina central que evalúa el código Lisp es solo una función Lisp. Esto puede no ser una implementación de Lisp real o práctica, aún es diferente de la situación PASCAL, donde el código fuente no tiene una representación útil (que no sea una cadena o un archivo) y el motor de ejecución es mucho más código.

Así que en Lisp tenemos:

  • una representación sencilla para el código fuente (listas de símbolos)

  • una sencilla aplicación del evaluador en una sola función pequeña

Más allá de eso, no se necesita nada para implementar un evaluador de Lisp en Lisp.

Cuestiones relacionadas