sicp.io
1.1.5 · Условные выражения и предикаты

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

Используйте if, cond и составные предикаты для выбора одной ветви, а затем понаблюдайте, как and и or останавливаются перед ненужными выражениями.

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

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

  • Чтение предиката как выражения, управляющего последующим путем вычисления
  • Отслеживание первого совпавшего предложения cond и запасной ветви else
  • Использование if для защиты операции, предварительное условие которой не выполнено
  • Запоминание того, что в совместимом со Scheme коде Lispex только #f считается ложью
  • Наблюдение сокращенного вычисления с помощью явных побочных эффектов

Условное выражение не вычисляет все ответы заранее, чтобы сделать выбор потом. Оно вычисляет проверку, выбирает один путь и оставляет другой путь невычисленным. classify проверяет предикаты cond сверху вниз. safe-ratio использует if, чтобы избежать деления при нулевом знаменателе. Цитированный символ non-false выбирает истинную ветвь, потому что только #f считается ложью.

Формы and и or являются управляющими формами, а не обычными процедурами. and останавливается на первом ложном значении, а or останавливается на первом значении, отличном от #f. Вторая программа фиксирует только те операнды, до которых фактически дошло выполнение, показывая пропущенные выражения через их отсутствие. Этот конечный запуск демонстрирует выбранный путь, а не все возможные стратегии оптимизатора или реализации.

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

    Первая программа возвращает (negative zero small-positive large-positive undefined 5 truthy). Вторая возвращает (#f selected (or-ran and-ran)), а две метки с окончанием skipped никогда не попадают в visits.

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

    Найдите каждый предикат перед его выбранной ветвью. Убедитесь, что выражение деления отсутствует, когда знаменатель равен нулю. В программе с сокращенным вычислением найдите первое значение #f в and и первое значение, отличное от #f, в or, затем проверьте отсутствие событий применения для обоих пропущенных вызовов record!.

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

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

    Добавьте предикат between? и используйте его внутри cond для различения отрицательных чисел, нуля, однозначных положительных чисел, двузначных положительных чисел и больших значений. Затем добавьте один вызов record! после заведомо ложного операнда and и спрогнозируйте, выполнится ли он.

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

    Вспомогательный предикат может объединять сравнения нижней и верхней границ с помощью and. Все, что расположено после ложного операнда and, недостижимо в этом вычислении.

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

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