error-handlingcommon-lispsbclcondition-system

How to continue normal execution after exception in Common Lisp?


I want to catch unbound-variable exceptions and avoid them, creating some variables on-the-fly without execution breaks. I'm trying to use handler-bind with invoke-restart in the following code:

(defmacro my-progn (&rest rest)
  `(handler-bind
    ((unbound-variable
      (lambda (x)
        (progn
          ;(format t "UNBOUND VAR: ~a~%"
          ;  (symbol-name (cell-error-name x)))
          (invoke-restart 'just-continue)))))
    (progn ,@(mapcar (lambda (x)
                      `(restart-case ,x (just-continue () "XXXX"))) rest))))

(my-progn
  (print "AAA")
  (print xxxx) ;; xxxx is unbound
  (print "BBB"))

The result is:

"AAA"
"BBB" 

But I want to contiunue the execution of second print, just replacing unbound variable xxxx to string "XXXX":

"AAA"
"XXXX"
"BBB" 

Of course, I can wrap any symbol in the syntax tree with handler-bind, but I'm afraid this will produce a huge overhead.

Is there a way just to catch unbound-variable exceptions and continue code execution with the dynamically generated values instead of missing variables?


Solution

  • You can use the appropriate standard restart use-value.

    (handler-bind
        ((unbound-variable
          (lambda (c)
            (declare (ignore c))
            (use-value "XXXX"))))
      (print "AAA")
      (print xxxx)
      (print "BBB"))