restart-caseの実験

ようするにエラーの修復手段を処理関数側で用意し、呼び出す側は自由に選択できるってことかな?
Rubyとかならlowは例外だけを発生させて、lowとmidの間の階層でエラー修復手段つきの関数をつくるのだろうか。
Rubyみたいにスタックトレースにエラーメッセージを出すことってどうするんだろう?

(define-condition invalid (error) ((desc :initarg :desc :reader desc)
                                   (value :initarg :value :reader value)))
(defun low (arg)
  (if (eql arg 'invalid)
      (restart-case (error 'invalid
                           :desc (format nil "invalid error in low: value=~a" arg)
                           :value arg)
        (use-value (value) value)
        (validate (new-value) (low new-value)))
      (format nil "(~a)" arg)))

(defun mid ()
  (format nil "<~a>" (low 'invalid)))

;;;; high level functions

(defun cause-error ()
  (mid))
;; (cause-error)

(defun signal-and-set-low-result ()
  (handler-bind ((invalid (lambda (c)
                            (use-value
                             (let ((msg "invalid caught at high."))
                               (signal 'invalid :desc msg)
                               msg)))))
    (mid)))
;; (signal-and-set-low-result)
(defun reraise-error ()
  (handler-bind ((invalid (lambda (c)
                            (error "reraised error: ~*" c )))))
    (mid))
;; (reraise-error)
(defun set-low-result ()
  (handler-bind ((invalid (lambda (c)
                            (use-value
                             (format nil "invalid caught at high: ~a" (desc c))))))
    (mid)))
;; (set-low-result)

(defun set-new-arg-of-low ()
  (handler-bind ((invalid (lambda (c)
                            (declare (ignore c))
                            (invoke-restart 'validate
                             'fixed))))
    (mid)))
;; (set-new-arg-of-low)

(defun handler-case-returns-result-of-error-clause ()
  (handler-case (mid)
    (invalid (c) 'invalid-handler)))
;; (handler-case-returns-result-of-error-clause)


CL-USER> (cause-error)
Condition INVALID was signalled.
   [Condition of type INVALID]

Restarts:
 0: [USE-VALUE] USE-VALUE
 1: [VALIDATE] VALIDATE
 2: [ABORT] Return to SLIME's top level.
 3: [TERMINATE-THREAD] Terminate this thread (#<THREAD "repl-thread" {AFEA8D9}>)
CL-USER> (signal-and-set-low-result)
"<invalid caught at high.>"
CL-USER> (reraise-error)
Condition INVALID was signalled.
   [Condition of type INVALID]

Restarts:
 0: [USE-VALUE] USE-VALUE
 1: [VALIDATE] VALIDATE
 2: [ABORT] Return to SLIME's top level.
 3: [TERMINATE-THREAD] Terminate this thread (#<THREAD "repl-thread" {AFEA8D9}>)
CL-USER> (set-low-result)
"<invalid caught at high: invalid error in low: value=INVALID>"
CL-USER> (set-new-arg-of-low)
"<(FIXED)>"
CL-USER> (handler-case-returns-result-of-error-clause)
INVALID-HANDLER