Песочница

Первое решающее правило

Соедините процедуры, условия, цитированные данные и граничные проверки в законченное правило срока возврата.

Этот шаг объединяет ранее изученные части в одно законченное правило. Политика намеренно мала. Невскрытый товар можно вернуть по 14-й день включительно. Формируйте привычку делать наглядными и решение, и его границу.

Опишите входы до кода

Процедура получает два входа.

  • days задаёт число дней после доставки.
  • opened? равно #t, если товар вскрыт, и #f в противном случае.

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

Напишите правило

LISPEX
(define (refund-decision days opened?)
  (if (and (<= days 14) (not opened?))
      '(decision allow)
      '(decision deny outside-refund-window)))

(refund-decision 9 #f)

Результат

OUTPUT
(decision allow)

Читайте проверку слева направо. Значение days не должно превышать 14, а opened? должно быть ложным. При невыполнении первого условия and сразу останавливается. if вычисляет только выбранное цитированное решение.

Метка отказа сделана намеренно консервативной. В реальной политике могут потребоваться отдельные причины для вариантов «слишком поздно» и «уже вскрыто». Это выбор продукта, а не скрытое поведение Лиспекса.

Проверяйте границу, а не только удачный случай

LISPEX
(list (refund-decision 14 #f)
      (refund-decision 15 #f)
      (refund-decision 9 #t))

Результат

OUTPUT
((decision allow) (decision deny outside-refund-window) (decision deny outside-refund-window))
СлучайЧто он показываетРешение
день 14, не вскрытвключённая границаразрешить
день 15, не вскрытпервое значение снаружиотказать
день 9, вскрытнезависимый провал второго условияотказать

Если позже <= заменят на <, первая строка изменится. Граничная таблица делает такое изменение наглядным при проверке.

Сохраняйте детерминизм

Правило читает только свои аргументы. Оно не получает время с часов, не вызывает сервер и не читает изменяемое состояние приложения. Вызывающая сторона решает, как вычислить days, и передаёт это значение явно. При одинаковых двух значениях Лиспекса и одинаковых документированных ограничениях среды выполнения правило проходит тот же путь вычисления и даёт тот же наблюдаемый результат.

Это не доказывает справедливость политики, её юридическую достаточность или опору на точные реальные данные. Лиспекс делает вычисление проверяемым, а окружающее приложение остаётся ответственным за происхождение входа и внешнее действие.

Упражнение

Измените правило так, чтобы невскрытый товар разрешалось вернуть по 30-й день включительно. Добавьте два граничных вызова, которые показывают последнее разрешённое и первое отклонённое значение.

Показать один ответ

Замените (<= days 14) на (<= days 30) и выполните два граничных вызова.

LISPEX
(list (refund-decision 30 #f)
      (refund-decision 31 #f))

Ожидается ((decision allow) (decision deny outside-refund-window)).

Готовы к шагу 6?

Теперь вы умеете читать вызовы, определять процедуру, сохранять список как данные, выбирать ветвь и проверять границу. Следующим шагом станет Где выполняется ваша программа.

Отсюда можно и ответвиться от курса.