Custom Errors in Lisp
(defpackage :custom-errors
(:use :cl))
(in-package :custom-errors)
;; A custom error type usually has the suffix "Error".
(defstruct arg-error
arg
message)
;; Adding this error-message method makes arg-error behave like an error.
(defmethod error-message ((e arg-error))
(format nil "~A - ~A" (arg-error-arg e) (arg-error-message e)))
(defun f (arg)
(if (= arg 42)
;; Return our custom error.
(values -1 (make-arg-error :arg arg :message "can't work with it"))
(values (+ arg 3) nil)))
(defun main ()
;; In Common Lisp, we don't have a direct equivalent to errors.As,
;; but we can check the type of the error and extract information from it.
(multiple-value-bind (result err) (f 42)
(declare (ignore result))
(if (typep err 'arg-error)
(progn
(format t "~A~%" (arg-error-arg err))
(format t "~A~%" (arg-error-message err)))
(format t "err doesn't match arg-error~%"))))
(main)This code demonstrates how to create and use custom error types in Common Lisp. Here’s a breakdown of the translation:
We define a package
custom-errorsto encapsulate our code.We create a custom error type
arg-errorusingdefstruct. This is similar to defining a custom struct in other languages.We define an
error-messagemethod for ourarg-errortype. This is analogous to implementing theError()method in other languages.The
ffunction is translated directly. It returns multiple values in Lisp, which is similar to returning multiple values in other languages.In the
mainfunction, we usemultiple-value-bindto capture both return values fromf.Instead of
errors.As, we usetypepto check if the error is of typearg-error. If it is, we print its contents.
To run this program, you would typically save it to a file (e.g., custom-errors.lisp) and then load and run it in a Common Lisp REPL:
$ sbcl --load custom-errors.lisp
42
can't work with itThis example shows how Common Lisp handles custom error types and multiple return values, which are concepts similar to those in the original code.