
4.1. Метациклический интерпретатор
359
Напри мер, если мы скормим вычислителю опреде ление factorial, как показ ано на
рисун ке 4.3, он сможет считать факториалы.
С этой точки зрения, наш вычислитель-интерпретатор выглядит как универсальная
машина (universal machine). Она имитирует другие машины, представленные в виде
Лисп-программ
19
. Это замечательное ус тройство. Попробуйте представить себе анало-
гичный вычислитель для электрических схем. Это была бы схема, которой на вход по-
ступает сигнал, кодирующий устройство какой-то другой схемы, например, фильтра.
Восприняв этот вход, наша схема-вычислитель стала бы работать как фильтр, соответ-
ствующий описанию. Такая универсальная электрическая схема имеет почти невообра-
зимую сложность. Удивительно, что и нтерпретатор программ — сам по себе программа
довольно простая
20
.
Еще одна замечательная черта интерпретатора заключается в том, что он служит
мостом между объектами данных, которыми манипулирует язык программирования, и
самим языком. Представим себе, что работает программа интерпретатора (реализован-
ная на Лиспе), и что пользователь вводит выражения в интерпретатор и рассматривае т
результаты. С точки зрения пользователя, входное выражение вроде (* x x) является
выражением языка программирования, которое интерпретатор должен выполнить. Одна-
ко с точки зрения интерпретатора это всего лишь список (в данном случае, список из
трех символов: *, x и x), с которым нужно работать по ясно очерченным правилам.
Нас не должно смущать, что программы пользователя являются данными для интер-
претатора. На самом деле, иногда бывает удобно и гнорировать это различие и, предостав-
ляя пользовательским программам доступ к eval, давать пользователю возможность
явным образом вычислить объект данных как выражение Лиспа. Во многих диалектах
Лиспа имеется элементарная процедура eval, которая в виде аргументов берет выра-
жение и окружение, и вычисляет выражение в указанном окружении
21
. Таким о бразом,
19
То, что машины описаны на языке Лисп, несущественно. Если дать нашему интерпретатору программу на
Лиспе, которая ведет себя как вычислитель для какого-нибудь другого языка, скажем, Си, то вычислитель для
Лиспа будет имитировать вычислитель для Си, который, в свою очередь, способен сымитировать любую маши-
ну, описанную в виде программы на Си. Подобн ым образом, написание интерпретатора Л испа на Си порождает
программу на Си, способную выполнить любую программу на Лиспе. Главная идея здесь состоит в том, что
любой вычислитель способен имитировать любой другой. Таким образом, понятие «того, что в принципе можно
вычислить» (если не принимать во внимание практические вопросы времени и памяти, потребной для вычис-
ления), независимо от языка компьютера и выражает глубинное понятие вычислимости (computability). Это
впервые было ясно показано Аланом М. Тьюрингом (1912-1954) , чья статья 1936 года заложила основы теоре-
тической информатики. В этой статье Тьюринг представил простую модель вычислений, — теперь известную
как машина Тьюринга (Turing machine), — и утверждал, что любой «эффективный процесс» выразим в виде
программы для такой машины. (Этот аргумент известен как тезис Чёрча-Тьюринга (Church-Turing thesis).)
Затем Тьюринг реализовал универсальную машину, т. е. машину Тьюринга, которая работает как вычислитель
для программ машин Тьюринга. При помощи этой схемы рассуждений он показал, что существуют коррекно
поставленные задачи, которые не могут быть решены машиной Тьюринга (см. упражнение 4.15), а следователь-
но не могут быть сформулированы в виде «эффективного процесса». Позднее Тьюринг внес фундаментальный
вклад и в развитие практической информатики. Например, ему принадлежит идея структурирования программ
с помощью подпрограмм общего назначения. Биографию Тьюринга можно найти в Hodges 1983.
20
Некоторые считают странным, что вычислитель, реализованный с помощью относительно простой проце-
дуры, способен имитировать программы, более сложные, чем он сам. Существование универсальной машины-
вычислителя — глубокое и важное свойство вычисления. Теория рекурсии (recursion theory), отрасль матема-
тической логики, занимается логическими пределами вычислимости. В прекрасной книге Дугласа Хофштадтера
«Гёдель, Эшер, Бах» (Hofstadter 1979) исследуются некоторые из этих идей.
21
Предупреждение: эта процедура eval — не то же самое, что процедура eval, реализованная нами в
разделе 4.1.1, потому что она работает с настоящими окружениями, а не с искусственными структурами