Предикаты и выбор одной ветви вычисления
Используйте if, cond и составные предикаты для выбора одной ветви, а затем понаблюдайте, как and и or останавливаются перед ненужными выражениями.
Как программа может принимать решение без вычисления работы, относящейся к каждой возможной ветви?
- Чтение предиката как выражения, управляющего последующим путем вычисления
- Отслеживание первого совпавшего предложения cond и запасной ветви else
- Использование if для защиты операции, предварительное условие которой не выполнено
- Запоминание того, что в совместимом со Scheme коде Lispex только #f считается ложью
- Наблюдение сокращенного вычисления с помощью явных побочных эффектов
Условное выражение не вычисляет все ответы заранее, чтобы сделать выбор потом. Оно вычисляет проверку, выбирает один путь и оставляет другой путь невычисленным. classify проверяет предикаты cond сверху вниз. safe-ratio использует if, чтобы избежать деления при нулевом знаменателе. Цитированный символ non-false выбирает истинную ветвь, потому что только #f считается ложью.
Формы and и or являются управляющими формами, а не обычными процедурами. and останавливается на первом ложном значении, а or останавливается на первом значении, отличном от #f. Вторая программа фиксирует только те операнды, до которых фактически дошло выполнение, показывая пропущенные выражения через их отсутствие. Этот конечный запуск демонстрирует выбранный путь, а не все возможные стратегии оптимизатора или реализации.
- Вывод
- —
- Значение
- —
- Диагностика
- —
Первая программа возвращает (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, недостижимо в этом вычислении.