Ремонт принтеров, сканнеров, факсов и остальной офисной техники


назад Оглавление вперед




[114]

(prompt-for-input input-prompt) (let ((input (read)))

(let ((output (eval input the-global-environment)))

(announce-output output-prompt)

(user-print output))) (driver-loop))

(define (prompt-for-input string)

(newline) (newline) (display string) (newline))

(define (announce-output string)

(newline) (display string) (newline))

Мы пользуемся специальной процедурой вывода user-print, чтобы не печатать окружение составных процедур, которое может быть очень длинным списком, и даже может содержать циклы.

(define (user-print object)

(if (compound-procedure? object)

(display (list compound-procedure

(procedure-parameters object) (procedure-body object) <procedure-env>)) (display object)))

Теперь для запуска интерпретатора нам остается только проинициализиро-вать глобальное окружение и войти в управляющий цикл. Вот пример работы интерпретатора:

(define the-global-environment (setup-environment))

(driver-loop)

;;; Ввод M-Eval: (define (append x y)

(if (null? x) y

(cons (car x)

(append (cdr x) y))))

;;; Значение M-Eval: ok

;;; Ввод M-Eval:

(append (a b c) (d e f))

;;; Значение M-Eval:

(a b c d e f)

Упражнение 4.14.

Ева Лу Атор и Хьюго Дум экспериментируют с метациклическим интерпретатором каждый по отдельности. Ева вводит определение map и запускает несколько тестовых программ с его использованием. Они замечательно работают. Хьюго, со своей стороны, ввел системную версию map как примитив метациклического интерпретатора. Когда он пытается его выполнить, все ломается самым ужасным образом. Объясните, почему у Хьюго map не работает, а у Евы работает.


720

Рис. 4.2: Программа вычисления факториала, изображенная в виде абстрактной машины.

4.1.5 Данные как программы

При рассмотрении программы на Лиспе, вычисляющей лисповские выражения, может быть полезна аналогия. Одна из возможных точек зрения на значение программы состоит в том, что программа описывает абстрактную (возможно, бесконечно большую) машину. Рассмотрим, например, знакомую нам программу для вычисления факториалов:

(define (factorial n) (if (= n 1) 1

(* (factorial (- n 1)) n)))

Можно считать эту программу описанием машины, которая содержит узлы для вычитания, умножения и проверки на равенство, двухпозиционный переключатель и еще одну факториал-машину. (Факториал-машина получается бесконечной, поскольку она содержит другую факториал-машину внутри себя.) На рисунке 4.2 изображена потоковая диаграмма факториал-машины, которая показывает, как спаяны ее части.

Подобным образом, мы можем рассматривать вычислитель как особого рода машину, которой подается в виде сырья описание другой машины. Обработав свои входные данные, вычислитель перестраивает себя так, чтобы моделировать описываемую машину. Например, если мы скормим вычислителю определение factorial, как показано на рисунке 4.3, он сможет считать факториалы.

С этой точки зрения, наш вычислитель-интерпретатор выглядит как универсальная машина (universal machine). Она имитирует другие машины, представленные в виде Лисп-программ.19 Это замечательное устройство. Попробуйте представить себе аналогичный вычислитель для электрических схем. Это

19То, что машины описаны на языке Лисп, несущественно. Если дать нашему интерпретатору программу на Лиспе, которая ведет себя как вычислитель для какого-нибудь другого языка, скажем, Си, то вычислитель для Лиспа будет имитировать вычислитель для Си, который, в свою очередь, способен сымитировать любую машину, описанную в виде программы на Си. Подобным образом, написание интерпретатора Лиспа на Си порождает программу на Си, способную выполнить

6


eval

r Г

(define (factorial (if (= n 1)\s

1

ч (* (factorial (- n 1)) n)))

Рис. 4.3: Вычислитель, моделирующий факториальную машину.

была бы схема, которой на вход поступает сигнал, кодирующий устройство какой-то другой схемы, например, фильтра. Восприняв этот вход, наша схема-вычислитель стала бы работать как фильтр, соответствующий описанию. Такая универсальная электрическая схема имеет почти невообразимую сложность. Удивительно, что интерпретатор программ - сам по себе программа довольно

20

простая.20

Еще одна замечательная черта интерпретатора заключается в том, что он служит мостом между объектами данных, которыми манипулирует язык программирования, и самим языком. Представим себе, что работает программа интерпретатора (реализованная на Лиспе), и что пользователь вводит выражения в интерпретатор и рассматривает результаты. С точки зрения пользователя, входное выражение вроде (* x x) является выражением языка программирования, которое интерпретатор должен выполнить. Однако с точки зрения интерпретатора это всего лишь список (в данном случае, список из трех символов: * , x и x), с которым нужно работать по ясно очерченным правилам.

любую программу на Лиспе. Главная идея здесь состоит в том, что любой вычислитель способен имитировать любой другой. Таким образом, понятие «того, что в принципе можно вычислить» (если не принимать во внимание практические вопросы времени и памяти, потребной для вычисления), независимо от языка компьютера и выражает глубинное понятие вычислимости (computability). Это впервые было ясно показано Аланом М. Тьюрингом (1912-1954), чья статья 1936 года заложила основы теоретической информатики. В этой статье Тьюринг представил простую модель вычислений, - теперь известную как машина Тьюринга (Turing machine), - и утверждал, что любой «эффективный процесс» выразим в виде программы для такой машины. (Этот аргумент известен как тезис Чёрча-Тьюринга (Church-Turing thesis).) Затем Тьюринг реализовал универсальную машину, т. е. машину Тьюринга, которая работает как вычислитель для программ машин Тьюринга. При помощи этой схемы рассуждений он показал, что существуют коррекно поставленные задачи, которые не могут быть решены машиной Тьюринга (см. упражнение 4.15), а следовательно не могут быть сформулированы в виде «эффективного процесса». Позднее Тьюринг внес фундаментальный вклад и в развитие практической информатики. Например, ему принадлежит идея структурирования программ с помощью подпрограмм общего назначения. Биографию Тьюринга можно найти в Hodges 1983.

20Некоторые считают странным, что вычислитель, реализованный с помощью относительно простой процедуры, способен имитировать программы, более сложные, чем он сам. Существование универсальной машины-вычислителя - глубокое и важное свойство вычисления. Теория рекурсии (recursion theory), отрасль математической логики, занимается логическими пределами вычислимости. В прекрасной книге Дугласа Хофштадтера «Гёдель, Эшер, Бах» (Hofstadter 1979) исследуются некоторые из этих идей.



[стр.Начало] [стр.1] [стр.2] [стр.3] [стр.4] [стр.5] [стр.6] [стр.7] [стр.8] [стр.9] [стр.10] [стр.11] [стр.12] [стр.13] [стр.14] [стр.15] [стр.16] [стр.17] [стр.18] [стр.19] [стр.20] [стр.21] [стр.22] [стр.23] [стр.24] [стр.25] [стр.26] [стр.27] [стр.28] [стр.29] [стр.30] [стр.31] [стр.32] [стр.33] [стр.34] [стр.35] [стр.36] [стр.37] [стр.38] [стр.39] [стр.40] [стр.41] [стр.42] [стр.43] [стр.44] [стр.45] [стр.46] [стр.47] [стр.48] [стр.49] [стр.50] [стр.51] [стр.52] [стр.53] [стр.54] [стр.55] [стр.56] [стр.57] [стр.58] [стр.59] [стр.60] [стр.61] [стр.62] [стр.63] [стр.64] [стр.65] [стр.66] [стр.67] [стр.68] [стр.69] [стр.70] [стр.71] [стр.72] [стр.73] [стр.74] [стр.75] [стр.76] [стр.77] [стр.78] [стр.79] [стр.80] [стр.81] [стр.82] [стр.83] [стр.84] [стр.85] [стр.86] [стр.87] [стр.88] [стр.89] [стр.90] [стр.91] [стр.92] [стр.93] [стр.94] [стр.95] [стр.96] [стр.97] [стр.98] [стр.99] [стр.100] [стр.101] [стр.102] [стр.103] [стр.104] [стр.105] [стр.106] [стр.107] [стр.108] [стр.109] [стр.110] [стр.111] [стр.112] [стр.113] [стр.114] [стр.115] [стр.116] [стр.117] [стр.118] [стр.119] [стр.120] [стр.121] [стр.122] [стр.123] [стр.124] [стр.125] [стр.126] [стр.127] [стр.128] [стр.129] [стр.130] [стр.131] [стр.132] [стр.133] [стр.134] [стр.135] [стр.136] [стр.137] [стр.138] [стр.139] [стр.140] [стр.141] [стр.142] [стр.143] [стр.144] [стр.145] [стр.146] [стр.147] [стр.148] [стр.149] [стр.150] [стр.151] [стр.152] [стр.153] [стр.154] [стр.155] [стр.156] [стр.157] [стр.158] [стр.159] [стр.160] [стр.161] [стр.162] [стр.163] [стр.164] [стр.165] [стр.166] [стр.167] [стр.168] [стр.169] [стр.170] [стр.171] [стр.172] [стр.173] [стр.174] [стр.175] [стр.176] [стр.177] [стр.178] [стр.179] [стр.180] [стр.181] [стр.182] [стр.183] [стр.184] [стр.185] [стр.186] [стр.187] [стр.188] [стр.189] [стр.190] [стр.191] [стр.192] [стр.193] [стр.194] [стр.195] [стр.196]