First Decision Rule

Combine procedures, conditions, quoted data, and boundary tests into a complete refund-window decision rule.

This step combines the earlier pieces into one complete rule. The policy is deliberately small. An unopened item may be refunded through day 14. Build the habit of making both the decision and its boundary visible.

State the inputs before the code

The procedure receives two inputs.

  • days is the number of days since delivery.
  • opened? is #t when the item has been opened, otherwise #f.

This lesson assumes the caller already supplied a valid non-negative day count and a boolean. Input validation is a separate decision boundary covered in Handling Errors Deterministically.

Write the rule

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

(refund-decision 9 #f)

Result

OUTPUT
(decision allow)

Read the test from left to right. days must be at most 14, and opened? must be false. and stops immediately if the first condition fails. if evaluates only the selected quoted decision.

The denied label is intentionally conservative. In a real policy you may want separate reasons for “too late” and “already opened.” That is a product choice, not a hidden behavior of Lispex.

Test the boundary, not just the happy path

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

Result

OUTPUT
((decision allow) (decision deny outside-refund-window) (decision deny outside-refund-window))
CaseWhy it mattersDecision
day 14, unopenedthe inclusive edgeallow
day 15, unopenedthe first value outside the windowdeny
day 9, openedthe second condition independently failsdeny

If someone later changes <= to <, the first row changes. A boundary table makes that change reviewable.

Keep the rule deterministic

The rule reads only its arguments. It does not fetch a clock, call a server, or read mutable application state. The caller decides how to calculate days and passes that value explicitly. Given the same two Lispex values under the same documented runtime limits, the rule follows the same evaluation path and produces the same observable result.

This does not prove that the refund policy is fair, legally sufficient, or based on accurate real-world data. Lispex makes the computation inspectable, and the surrounding application remains responsible for input provenance and the external action.

Exercise

Change the rule so an unopened item is allowed through day 30. Add the two boundary calls that show the last accepted and first rejected values.

Show one answer

Change (<= days 14) to (<= days 30), then run the two boundary calls.

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

The expected result is ((decision allow) (decision deny outside-refund-window)).

Ready for Step 6?

You can now read calls, define a procedure, preserve a list as data, choose a branch, and test a boundary. The next step is Where Your Program Runs.

You can also branch out from the course here.