sicp.io
4.2.1 · Нормальный порядок и аппликативный порядок

Порядок вычислений и момент работы над аргументом

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

Вопрос для размышления

Как два вычислителя могут возвращать одно и то же значение, выполняя при этом разный объем работы с аргументами?

  • Вычисление каждого операнда перед строгим составным применением
  • Связывание невычисленных выражений операндов как thunk нормального порядка
  • Форсирование thunk только тогда, когда поиск переменной требует ее значение
  • Наблюдение неиспользуемого аргумента при обеих стратегиях
  • Наблюдение дублирования работы при двукратном обращении к параметру нормального порядка
  • Сравнение двух явных стратегий вычисления guest

Процедура strict-eval вычисляет операнд перед применением составной процедуры. Поэтому игнорируемый аргумент x вызывает probe один раз, даже если тело возвращает 1. Процедура normal-eval вместо этого связывает x с thunk, содержащим выражение операнда и его окружение. Поскольку тело никогда не выполняет поиск x, процедура probe не запускается.

Во втором выражении тело использует x дважды. Строгое вычисление выполняет probe один раз и связывает полученное значение 10. Немемоизированный вычислитель нормального порядка форсирует сохраненное выражение при каждом поиске, поэтому probe запускается дважды. Оба возвращают 20, но объем работы различается. Эти два вычислителя представляют собой явные модели guest, и они не меняют порядок вычислений выполняющей их программы хоста Lispex.

Код SICP4,328 из 1,048,576 байт UTF-8
Примеры
Результат
Вывод
Значение
Диагностика
Трасса выполнения0 / 0 событий
    Запуски происходят внутри браузера с отображением результата программы и трассы выполнения.
    Ожидаемый результат

    Программа возвращает ((unused (1 1) (1 0)) (duplicated (20 1) (20 2))). Каждая пара содержит значение, за которым следует количество вызовов probe.

    На что обратить внимание в трассе

    В strict-eval найдите вызов probe до начала выполнения составного тела. В normal-eval проследите за каждым связыванием параметра с thunk и убедитесь, что оно форсируется только при поиске переменной. Неиспользуемое тело не выполняет форсирование, а тело с дублированием обращается к одному и тому же выражению thunk дважды, поскольку эта модель намеренно не выполняет мемоизацию.

    Попробуйте сами

    Измените программу и сравните результат.

    Добавьте ((lambda (x) (+ x (+ x x))) (probe 4)). Спрогнозируйте количество вызовов probe для строгого вычисления и нормального порядка, а затем добавьте ячейку мемоизации в thunk и спрогнозируйте количество вызовов при вызове по необходимости.

    Показать подсказку

    Строгое вычисление вычисляет аргумент один раз. Немемоизированный нормальный порядок выполняет вычисление один раз на каждый поиск x. Мемоизированный thunk вычисляет значение не более одного раза.

    Завершить этот урок

    В этой главе пройдено 0 из 23 урока0%