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.