2010-12-27 13 views
10

Me pregunto sobre el propósito, o tal vez más correctamente, las tareas del "lector" durante la interpretación/compilación de los programas Lisp.¿Cuáles son las tareas del "lector" durante la interpretación de Lisp?

A partir de la investigación previa a la pregunta que acabo de hacer, me parece que un lector (particular de Clojure en este caso) puede considerarse como un "preprocesador sintáctico". Sus deberes principales son la expansión de macros de lector y formas primitivas. Por lo tanto, dos ejemplos:

'cheese   --> (quote cheese) 
{"a" 1 "b" 2} --> (array-map "a" 1 "b" 2) 

para que el lector se lleva en el texto de un programa (que consiste en S-expresiones) y luego se construye y devuelve un estructura de datos en memoria que se puede evaluar directamente.

¿Qué tan lejos de la verdad es esto (y he simplificado demasiado todo el proceso)? ¿Qué otras tareas realiza el lector? Teniendo en cuenta la virtud de Lisps es su homoiconicity (código como datos), ¿por qué hay una necesidad de análisis léxico (si es realmente comparable al trabajo del lector)?

Gracias!

Respuesta

20

Generalmente, el lector en Lisp lee s-expressions y devuelve estructuras de datos. READ es una operación de E/S: la entrada es una secuencia de caracteres y la salida es datos Lisp.

La impresora hace lo contrario: toma los datos de Lisp y los emite como una secuencia de caracteres. Por lo tanto, también puede imprimir datos Lisp a s-expresiones externas.

Tenga en cuenta que interpretación significa algo específico: ejecutar el código por un intérprete. Pero muchos sistemas Lisp (incluido Clojure) están utilizando un compilador. Las tareas de calcular un valor para un formulario Lisp generalmente se llaman evaluación. La evaluación se puede implementar por interpretación, por compilación o por una combinación de ambos.

S-Expression: expresiones simbólicas. Representación textual externa de datos. Externo significa que las expresiones s son lo que ves en los archivos de texto, cadenas, etc. Así que las expresiones s están hechas de caracteres en algunos medios, típicamente externos.

estructuras de datos Lisp: símbolos, listas, cadenas, números, caracteres, ...

lector: lee s-expresiones y devuelve estructuras de datos Lisp.

Tenga en cuenta que las expresiones s también se utilizan para codificar el código fuente de Lisp.

En algunos dialectos Lisp, el lector es programable y manejable en la tabla (a través de la llamada tabla de lectura). Esta tabla de lectura contiene funciones de lector para caracteres. Por ejemplo, el carácter quote 'está vinculado a una función que lee una expresión y devuelve el valor de (list' quote expression). Los caracteres numéricos 0..9 están ligados a funciones que leen un número (en realidad esto podría ser más complejo, ya que algunos Lisps permiten que los números se lean en bases diferentes).

Las expresiones S proporcionan la sintaxis externa para estructuras de datos.

Los programas Lisp se escriben en forma externa mediante s-expressions.Pero no todos los s-expresiones son válidos los programas Lisp:

(if a b c d e) is usually not a valid Lisp program 

la sintaxis de Lisp por lo general se define en la parte superior de los datos de Lisp.

SI tiene, por ejemplo, la siguiente sintaxis (en Common Lisp http://www.lispworks.com/documentation/HyperSpec/Body/s_if.htm):

if test-form then-form [else-form] 

Por lo tanto, espera que una prueba de la forma, una forma de continuación, y una persona en forma opcional.

como S-expresiones Los siguientes son válidos expresiones si:

(if (foo) 1 2) 
(if (bar) (foo)) 

Pero ya que los programas Lisp son formas, también podemos construir estas formas usando programas Lisp:

(lista de 'si' (foo) 1 2) es un programa Lisp que devuelve una forma IF válida.

CL-USER 24 > (describe (list 'if '(foo) 1 2)) 

(IF (FOO) 1 2) is a LIST 
0  IF 
1  (FOO) 
2  1 
3  2 

Esta lista se puede ejecutar, por ejemplo, con EVAL. EVAL espera formularios de lista, no s-expresiones. Recuerde que las expresiones s son solo una representación externa. Para crear un formulario Lisp, necesitamos LEERLO.

Es por eso que se dice que es el código de datos. Los formularios Lisp se expresan como estructuras internas de datos Lisp: listas, símbolos, números, cadenas ... En la mayoría de los demás lenguajes de programación, el código es texto sin formato. En Lisp s-expresiones son texto sin formato. Cuando se lee con la función LEER, las expresiones s se convierten en datos.

Por lo tanto, la interacción básica de nivel superior en Lisp se llama REPL, Leer Eval Print Loop. Es un bucle que lee repetidamente una s-expresión, evalúa la forma Lisp y lo imprime:

READ : s-expression -> lisp data 
EVAL : lisp form -> resulting lisp data 
PRINT: lisp data -> s-expression 

Así que el más primitivo REPL es:

(loop (print (eval (read)))) 

Por lo tanto, desde un punto de vista conceptual, para responder a su pregunta, durante la evaluación el lector no hace nada. No está involucrado en la evaluación. La evaluación se realiza mediante la función EVAL. El lector es invocado por una llamada a LEER. Como EVAL usa estructuras de datos Lisp como entrada (y no como expresiones s), el lector se ejecuta antes de que se evalúe el formulario Lisp (por ejemplo, por interpretación o compilándolo y ejecutándolo).

+3

Gracias por la buena aclaración. Entonces, uno podría decir que el lector lee en los datos del programa como texto sin formato estructurado como expresiones S y devuelve una estructura de datos Lisp. No evalúa ninguna de esas expresiones, sino que simplemente las representa en la memoria de una manera que se puede evaluar con eficacia. Ahora veo más claramente la diferencia entre un evaluador (según el capítulo "abstracción metacircular" del SICP en el que se presenta un simple evaluador de lisp-in-lisp) y un intérprete completo. – Andrew

+4

@Andrew: correcto. En general, el lector no evalúa las cosas. Simplemente crea una estructura de datos Lisp para la expresión s. Ahora un evaluador podría interpretar estas estructuras de datos internas: la fase lexer ya está hecha. A menudo, estos programas como datos se compilan a máquina o código de bytes en un paso intermedio. Tenga en cuenta también que, por ejemplo, el lector de Common Lisp tiene la capacidad de evaluar cosas. '(1 2 #. (+ 1 2)) regresa (1 2 3). #. es una macro de lector que evalúa la siguiente expresión en tiempo de lectura. También se puede implementar un comportamiento adicional a través de tablas de lectura. –

Cuestiones relacionadas