Next: , Previous: , Up: Interpreting Error Messages   [Contents][Index]


4.4.3 The Processing Path

The processing path is mainly useful for debugging macros, so if you don’t write macros, you can ignore the processing path. Consider this example:

(defun foo (n)
  (dotimes (i n *undefined*)))

Compiling results in this error message:

In: DEFUN FOO
  (DOTIMES (I N *UNDEFINED*))
--> DO BLOCK LET TAGBODY RETURN-FROM 
==>
  (PROGN *UNDEFINED*)
Warning: Undefined variable: *UNDEFINED*

Note that do appears in the processing path. This is because dotimes expands into:

(do ((i 0 (1+ i)) (#:g1 n))
    ((>= i #:g1) *undefined*)
  (declare (type unsigned-byte i)))

The rest of the processing path results from the expansion of do:

(block nil
  (let ((i 0) (#:g1 n))
    (declare (type unsigned-byte i))
    (tagbody (go #:g3)
     #:g2    (psetq i (1+ i))
     #:g3    (unless (>= i #:g1) (go #:g2))
             (return-from nil (progn *undefined*)))))

In this example, the compiler descended into the block, let, tagbody and return-from to reach the progn printed as the actual source. This is a place where the “actual source appears in explanation” rule was applied. The innermost actual source form was the symbol *undefined* itself, but that also appeared in the explanation, so the compiler backed out one level.