Главная » Просмотр файлов » Х. Абельсон, Дж. Дж. Сассман, Дж. Сассман - Структура и интерпретация компьютерных программ

Х. Абельсон, Дж. Дж. Сассман, Дж. Сассман - Структура и интерпретация компьютерных программ (1108516), страница 85

Файл №1108516 Х. Абельсон, Дж. Дж. Сассман, Дж. Сассман - Структура и интерпретация компьютерных программ (Х. Абельсон, Дж. Дж. Сассман, Дж. Сассман - Структура и интерпретация компьютерных программ) 85 страницаХ. Абельсон, Дж. Дж. Сассман, Дж. Сассман - Структура и интерпретация компьютерных программ (1108516) страница 852019-04-28СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 85)

Метаязыковая абстракциямодифицируя этот интерпретатор. В самом деле, часто изобретение нового языка начинается с того, что пишут интерпретатор, который встраивает новый язык в существующийязык высокого уровня. Например, если нам хочется обсудить какую-то деталь предлагаемой модификации Лиспа с другим членом Лисп-сообщества, мы можем предъявить емуинтерпретатор, в котором эта модификация реализована. Тогда наш адресат может поэкспериментировать с новым интерпретатором и послать в ответ свои замечания в видедальнейших модификаций. Реализация на высокоуровневой основе не только упрощаетпроверку и отладку вычислителя; такое встраивание к тому же позволяет разработчикуслизывать31 черты языка-основы, как наш встроенный интерпретатор Лиспа использовал примитивы и структуру управления нижележащего Лиспа.

Только позже (да и то невсегда) разработчику приходится брать на себя труд построения полной реализации нанизкоуровневом языке или в аппаратуре. В этом разделе и следующем мы изучаем некоторые вариации на тему Scheme, которые значительно увеличивают ее выразительнуюсилу.4.2.1. Нормальный порядок вычислений и аппликативный порядоквычисленийВ разделе 1.1, где мы начали обсуждение моделей вычисления, мы указали, чтоScheme — язык с аппликативным порядком вычисления (applicative-order language), аименно, что все аргументы процедур в Scheme вычисляются в момент вызова. Напротив,в языках с нормальным порядком вычисления (normal-order language) вычисление аргументов процедур задерживается до момента, когда действительно возникает нужда вих значениях.

Если вычисление аргументов процедур откладывается как можно дольше(например, до того момента, когда они требуются какой-либо элементарной процедуре),то говорят о ленивом вычислении (lazy evaluation)32 . Рассмотрим процедуру(define (try a b)(if (= a 0) 1 b))Выполнение (try 0 (/ 1 0)) в Scheme приводит к ошибке. При ленивых вычислениях никакой ошибки не возникнет. Вычисление выражения даст результат 1, поскольку каргументу (/ 1 0) обращаться не понадобится.Примером использования ленивых вычислений может служить процедура unless:(define (unless condition usual-value exceptional-value)(if condition exceptional-value usual-value))которую можно использовать в выражениях вроде31 Слизывать (snarf): «Брать, в особенности большой документ или файл, с целью использовать с разрешения владельца или без оного».

Пролизывать (snarf down): «Слизывать, иногда с дополнительным значениемвосприятия, переработки или понимания». (Эти определения были слизаны из Steele et al. 1983. См. такжеRaymond 1993.)32 Терминологическая разница между выражениями «ленивый» и «нормальный порядок вычислений» несколько размыта. Обычно «ленивый» относится к механизмам конкретных интерпретаторов, а «нормальный порядок»к семантике языков независимо от способа реализации. Однако разделение здесь не жесткое, и часто эти термины употребляются как синонимы.4.2. SCHEME с вариациями: ленивый интерпретатор371(unless (= b 0)(/ a b)(begin (display "exception: returning 0")0))В аппликативном языке это не будет работать, потому что и обычное значение, и значение исключения будут выполнены еще до вызова unless (См.

упражнение 1.6). Преимущество ленивых вычислений в том, что некоторые процедуры, например, та же unless,могут выполнять полезные действия, даже если вычисление некоторых их аргументовспособно привести к ошибке или бесконечному циклу.Если тело процедуры начинает выполняться прежде, чем вычисляется ее аргумент, топроцедура называется нестрогой (non-strict) по этому аргументу. Если же аргумент вычисляется прежде, чем происходит вход в процедуру, то процедура называется строгой(strict) по этому аргументу33. В чисто аппликативном языке все процедуры строги повсем своим аргументам.

В языке с чисто нормальным порядком вычислений все составные процедуры нестроги по всем своим аргументам, а элементарные процедуры могутбыть и такими, и такими. Бывают также языки (см. упражнение 4.31), которые даютпрограммисту возможность явно обозначать строгость определяемых им процедур.Яркий пример процедуры, которой может быть полезно оказаться нестрогой, — этоcons (и вообще почти любой конструктор структур данных).

Можно производить полезные вычисления, составлять из элементов структуры данных и работать с ними, дажеесли значения элементов неизвестны. Вполне имеет смысл задача, например, посчитатьдлину списка, не зная значений его отдельных элементов. В разделе 4.2.3 мы развиваемэту идею и реализуем потоки из главы 3 в виде списков, составленных из нестрогихcons-пар.Упражнение 4.25.Предположим, что мы (в обычной Scheme с аппликативным порядком вычислений) определяемunless как показано выше, а затем определяем factorial через unless:(define (factorial n)(unless (= n 1)(* n (factorial (- n 1)))1))Что произойдет, если мы попытаемся вычислить (factorial 5)? Будут ли наши определенияработать в языке с нормальным порядком вычислений?Упражнение 4.26.Бен Битобор и Лиза П. Хакер расходятся во мнениях о важности ленивых вычислений для реализации конструкций вроде unless.

Бен указывает, что при аппликативном порядке unlessможно реализовать как особую форму. Лиза отвечает, что в таком случае unless будет простосинтаксисом, а не процедурой, которую можно использовать в сочетании с процедурами высших33 Термины «строгий» и «нестрогий» означают, в сущности, то же самое, что «аппликативный» и «нормальный» порядок вычислений, но только они относятся к отдельным процедурам и их аргументам, а не к языкув целом. На конференциях по языкам программирования можно услышать, как кто-нибудь говорит: «В языке Hassle с нормальным порядком вычислений есть несколько строгих примитивов.

Остальные процедурыпринимают аргументы через ленивое вычисление».372Глава 4. Метаязыковая абстракцияпорядков. Проясните детали в обеих позициях. Покажите, как реализовать unless в виде производного выражения (вроде cond или let), и приведите пример ситуации, когда имеет смысл,чтобы unless была процедурой, а не особой формой.4.2.2.

Интерпретатор с ленивым вычислениемВ этом разделе мы реализуем язык с нормальным порядком вычислений, которыйотличается от Scheme только тем, что все составные процедуры по всем аргументамнестроги. Элементарные процедуры по-прежнему будут строгими. Совсем несложно, модифицируя интерпретатор из раздела 4.1.1, добиться, чтобы интерпретируемый язык велсебя таким образом. Почти что все требуемые изменения сосредоточены вокруг механизма процедурного вызова.Основная идея состоит в том, что при вызове процедуры интерпретатор должен определить, какие аргументы требуется вычислить, а какие задержать. Задержанные аргументы не вычисляются, а преобразуются в объекты, называемые санками (thunks)34∗ .В санке должна содержаться информация, необходимая, чтобы вычислить значение аргумента, когда оно потребуется, и сделать это так, как будто оно вычислено во времявызова.

Таким образом, санк должен содержать выражение-аргумент и окружение, вкотором вычисляется вызов процедуры.Процесс вычисления санка называется вынуждением (forcing a thunk)35 Вообще говоря, санк вынуждается только тогда, когда требуется его значение: когда он передаетсяв элементарную процедуру, использующую его значение; когда он служит предикатом вусловном выражении; или когда он является значением оператора, который нужно применить как процедуру. Мы должны решить, будем ли мы мемоизировать (memoize)санки, как мы делали с задержанными объектами в разделе 3.5.1. При использованиимемоизации, когда санк вынуждается в первый раз, он запоминает вычисленное значение.

Последующие вызовы только возвращают запомненное значение, не вычисляя егозаново. Мы делаем выбор в пользу мемоизации, поскольку для многих приложений этоэффективнее. Здесь, однако, имеются тонкости36.34 Название «санк» было придумано в неформальной группе, которая обсуждала реализацию вызова по именив Алголе 60. Было замечено, что большую часть анализа («обдумывания», thinking about) выражения можнопроизводить во время компиляции; таким образом, во время выполнения выражение будет уже большей частью«обдумано» (thunk about — намеренно неверно образованная английская форма) (Ingerman et al.

1960).∗ В русскоязычной литературе слово thunk иногда переводится как «переходник». Нам кажется, что в данномслучае такой перевод мешал бы пониманию текста. — прим. перев.35 Это аналогично использованию слова force («вынудить», «заставить») для задержанных объектов, припомощи которых в главе 3 представлялись потоки. Основная разница между тем, что мы делаем здесь, итем, чем мы занимались в главе 3, состоит в том, что теперь мы встраиваем задержку и вынуждение винтерпретатор, и они применяются автоматически и единообразно во всем языке.36 Ленивые вычисления, совмещенные с мемоизацией, иногда называют методом передачи аргументов свызовом по необходимости (call by need), в отличие от вызова по имени (call by name). (Вызов по имени,введенный в Алголе 60, аналогичен немемоизированному ленивому вычислению.) Как проектировщики языкамы можем сделать интерпретатор мемоизирующим или немемоизирующим, или же оставить это на усмотрениепрограммистов (упражнение 4.31).

Как можно было ожидать из главы 3, этот выбор вызывает к жизни вопросы,особенно тонкие и запутанные в присутствии присваивания. (См. упражнения 4.27 и 4.29.) В замечательнойстатье Клингера (Clinger 1982) делается попытка прояснить многомерную путаницу, которая здесь возникает.4.2. SCHEME с вариациями: ленивый интерпретатор373Преобразование интерпретатораОсновная разница между ленивым интерпретатором и интерпретатором из раздела 4.1.1 состоит в обработке вызовов процедур внутри eval и apply.Ветка application? в eval принимает вид((application? exp)(apply (actual-value (operator exp) env)(operands exp)env))Это почти тот же код, что был в ветке application? в eval из раздела 4.1.1.

Однакопри ленивом вычислении мы зовем apply с выражениями операндов, а не с аргументами, которые получаются при их вычислении. Мы также передаем apply окружение,поскольку оно понадобится для построения санков, если нам хочется, чтобы аргуметы вычислялись с задержкой. Оператор мы по-прежнему вычисляем, потому что самаприменяемая процедура нужна apply, чтобы выбрать действие на основании ее типа(элементарная или составная) и применить ее.Всякий раз, когда нам требуется собственно значение выражения, мы вместо простогоeval пользуемся процедурой(define (actual-value exp env)(force-it (eval exp env)))чтобы, если значение выражения является санком, оно было вынуждено.Наша новая версия apply также почти совпадает с версией из раздела 4.1.1.

Разницасостоит в том, что eval передает ей невычисленные выражения: для элементарныхпроцедур (они строгие) мы вычисляем все аргументы и затем вызываем примитив; длясоставных процедур (они нестрогие) мы прежде применения процедуры замораживаемвсе аргументы.(define (apply procedure arguments env)(cond ((primitive-procedure? procedure)(apply-primitive-procedureprocedure(list-of-arg-values arguments env))) ; изменение((compound-procedure? procedure)(eval-sequence(procedure-body procedure)(extend-environment(procedure-parameters procedure)(list-of-delayed-args arguments env) ; изменение(procedure-environment procedure))))(else(error"Неизвестный тип процедуры -- APPLY" procedure))))Процедуры, обрабатывающие аргументы, почти такие же, как list-of-values из раздела 4.1.1, но только list-of-delayed-args замораживает аргументы, вместо того,чтобы их вычислять, а в list-of-arg-values вместо eval используется actualvalue:374Глава 4.

Метаязыковая абстракция(define (list-of-arg-values exps env)(if (no-operands? exps)’()(cons (actual-value (first-operand exps) env)(list-of-arg-values (rest-operands exps)env))))(define (list-of-delayed-args exps env)(if (no-operands? exps)’()(cons (delay-it (first-operand exps) env)(list-of-delayed-args (rest-operands exps)env))))Кроме того, нам требуется изменить в интерпретаторе обработку if, где вместо evalмы должны вызывать actual-value, чтобы значение предикатного выражения вычислялось прежде, чем мы проверим, истинно оно или ложно:(define (eval-if exp env)(if (true? (actual-value (if-predicate exp) env))(eval (if-consequent exp) env)(eval (if-alternative exp) env)))Наконец, нужно изменить процедуру driver-loop (раздел 4.1.4), чтобы она звалаactual-value вместо eval.

Характеристики

Список файлов книги

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6384
Авторов
на СтудИзбе
307
Средний доход
с одного платного файла
Обучение Подробнее