Ответ 1
Обычно читатель в Lisp считывает s-выражения и возвращает структуры данных. READ - операция ввода-вывода: Input - это поток символов, а вывод - Lisp.
Принтер выполняет обратное: он принимает данные Lisp и выводит их как поток символов. Таким образом, он также может печатать данные Lisp для внешних s-выражений.
Обратите внимание, что интерпретация означает что-то конкретное: выполнение кода интерпретатором. Но многие системы Lisp (включая Clojure) используют компилятор. Задачи вычисления значения для формы Lisp обычно называются оценкой. Оценка может быть выполнена путем интерпретации, путем компиляции или сочетанием обоих.
S-Expression: символические выражения. Внешнее текстовое представление данных. Внешние означает, что s-выражения - это то, что вы видите в текстовых файлах, строках и т.д. Таким образом, s-выражения сделаны из символов на некоторых, обычно внешних, средних.
Lisp структуры данных: символы, списки, строки, числа, символы,...
Reader: читает s-выражения и возвращает структуры данных Lisp.
Обратите внимание, что s-выражения также используются для кодирования исходного кода Lisp.
В некоторых диалектах Lisp читатель программируется и управляется таблицей (через так называемую таблицу чтения). Эта таблица чтения содержит функции считывателя для символов. Например, символ "quote" привязан к функции, которая считывает выражение и возвращает значение (выражение "quote quote" ). Числовые символы 0..9 привязаны к функциям, которые читают число (на самом деле это может быть более сложным, так как некоторые Lisps позволяют читать числа в разных базах).
S-выражения обеспечивают внешний синтаксис структур данных.
Lisp программы записываются во внешней форме с использованием s-выражений. Но не все s-выражения действительны Lisp программы:
(if a b c d e) is usually not a valid Lisp program
синтаксис Lisp обычно определяется поверх данных Lisp.
IF имеет, например, следующий синтаксис (в Common Lisp http://www.lispworks.com/documentation/HyperSpec/Body/s_if.htm):
if test-form then-form [else-form]
Поэтому он ожидает тестовую форму, затем-форму и необязательную форму else.
В качестве s-выражений допустимы IF-выражения:
(if (foo) 1 2)
(if (bar) (foo))
Но так как программы Lisp являются формами, мы можем также построить эти формы с помощью программ Lisp:
(list 'if' (foo) 1 2) - это программа Lisp, которая возвращает допустимую форму IF.
CL-USER 24 > (describe (list 'if '(foo) 1 2))
(IF (FOO) 1 2) is a LIST
0 IF
1 (FOO)
2 1
3 2
Этот список может быть, например, выполнен с EVAL. EVAL ожидает формы списка, а не s-выражения. Помните, что s-выражения - это только внешнее представление. Чтобы создать форму Lisp, нам нужно ПРОЧИТАТЬ ее.
Вот почему сказано, что код - это данные. Lisp формы выражаются как внутренние структуры данных Lisp: списки, символы, числа, строки,.... В большинстве других языков программирования код - это необработанный текст. В Lisp s-выражения являются исходным текстом. При чтении с помощью функции READ s-выражения преобразуются в данные.
Таким образом, основной уровень взаимодействия верхнего уровня в Lisp называется REPL, Read Eval Print Loop. Это LOOP, который повторно считывает s-выражение, оценивает форму Lisp и печатает ее:
READ : s-expression -> lisp data
EVAL : lisp form -> resulting lisp data
PRINT: lisp data -> s-expression
Итак, самый примитивный REPL:
(loop (print (eval (read))))
Таким образом, с концептуальной точки зрения, чтобы ответить на ваш вопрос, во время оценки читатель ничего не делает. Он не участвует в оценке. Оценка выполняется функцией EVAL. Читатель вызывается вызовом READ. Поскольку EVAL использует структуры данных Lisp в качестве входных (а не s-выражений), читатель запускается до получения формы Lisp (например, путем интерпретации или путем компиляции и выполнения ее).