Custom Errors in Scheme

It’s possible to use custom types as errors by implementing an error handling mechanism. Here’s an example that uses a custom type to explicitly represent an argument error.

(define-record-type <arg-error>
  (make-arg-error arg message)
  arg-error?
  (arg arg-error-arg)
  (message arg-error-message))

(define (arg-error->string ae)
  (string-append (number->string (arg-error-arg ae))
                 " - "
                 (arg-error-message ae)))

(define (f arg)
  (if (= arg 42)
      (values #f (make-arg-error 42 "can't work with it"))
      (values (+ arg 3) #f)))

(define (main)
  (let-values (((result error) (f 42)))
    (if (arg-error? error)
        (begin
          (display (arg-error-arg error))
          (newline)
          (display (arg-error-message error))
          (newline))
        (display "Error doesn't match arg-error"))))

(main)

In Scheme, we don’t have built-in error types like in some other languages. Instead, we can create our own error handling mechanism using record types and multiple return values.

We define a custom record type <arg-error> to represent our error. This is similar to defining a struct in other languages.

The arg-error->string procedure is equivalent to the Error() method in object-oriented languages. It creates a string representation of our error.

In the f procedure, we use values to return multiple values: the result and a potential error. This is similar to returning a tuple in some other languages.

In the main procedure, we use let-values to capture multiple return values from f. We then check if the error is of type <arg-error> using the arg-error? predicate.

To run this program, save it to a file (e.g., custom-errors.scm) and run it with a Scheme interpreter that supports R6RS or later (like Chez Scheme):

$ scheme --program custom-errors.scm
42
can't work with it

This example demonstrates how to implement a custom error handling mechanism in Scheme, even though Scheme doesn’t have a built-in error type system like some other languages.