Defensive programming

This chapter introduces the error facility of Chez Scheme, and describes how to use it to write programs that raise controlled errors with meaningful error messages instead of uncontrolled errors with incomprehensible error messages. The key point is that a program should raise an error in connection with what is being computed, not with how data are represented.

Resources

Raising errors

Chez Scheme’s errorf procedure makes it possible to raise an error. It takes at least two arguments: typically the name of a faulty procedure, a formatting directive, and further optional arguments, depending on the directive.

For example, here is a procedure implementing the quotient function cautiously:

(define cautious-quotient
  (lambda (i j)
    (if (number? i)
        (if (number? j)
            (if (= j 0)
                (errorf 'cautious-quotient
                        "cannot divide ~s by zero"
                        i)
                (quotient i j))
            (errorf 'cautious-quotient
                    "~s is not a number"
                    j))
        (errorf 'cautious-quotient
                "~s is not a number"
                i))))

This definition gives rise to the following scenario:

> (cautious-quotient 10 4)
2
> (cautious-quotient "10" 4)

Exception in cautious-quotient: "10" is not a number
Type (debug) to enter the debugger.
> (cautious-quotient 10 "4")

Exception in cautious-quotient: "4" is not a number
Type (debug) to enter the debugger.
> (cautious-quotient 10 0)

Exception in cautious-quotient: cannot divide 10 by zero
Type (debug) to enter the debugger.
>

Defensive programming

Thus equipped with errorf, we can write more user-friendly programs, such as cautious-quotient above or safe-fac below:

(define safe-fac
  (lambda (n)
    (letrec ([visit (lambda (i)
                      ...)])
      (if (and (integer? n)
               (>= n 0))
          (visit n)
          (errorf 'safe-fac "not a non-negative integer: ~s" n)))))

Applying safe-fac to a negative integer raises an error, instead of silently recursing below the base case.

Resources

Version

Created [11 Sep 2025]

Table Of Contents

Previous topic

The Scheme programming language, continued further

Next topic

Sets as lists