1

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?

Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
Pavel
  • 363
  • 1
  • 2
  • 14

1 Answers1

6

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"))
Rörd
  • 6,556
  • 21
  • 27
  • Thanks a lot! I have already found a solution with (defvar) and (contiune), but your variant is much better! – Pavel May 16 '20 at 18:52