Subject: Re: C++ style debugging
From: rpw3@rpw3.org (Rob Warnock)
Date: Mon, 21 Aug 2006 06:16:10 -0500
Newsgroups: comp.lang.lisp
Message-ID: <EZOdnQOKJIJnCHTZnZ2dnUVZ_s2dnZ2d@speakeasy.net>
Johan Ur Riise  <johan@riise-data.no> wrote:
+---------------
| "pTymN" <ptymn1447@gmail.com> writes:
| > Alex Mizrahi wrote:
| > ...very tired of (format t "DOT-PRODUCT = ~S~%" dot-product)
| > every time I want to check values.
| 
| I like this one. Could also be called EXHIBIT (from COBOL).
| 
| CL-USER> (defmacro display (&rest symbols)
|   (let ((format-statements 
|           (loop 
|              for sym in symbols
|              collect `(format t  "~a: ~s~%" ',sym ,sym))))
|     `(progn ,@format-statements)))
+---------------

Heh! A recurring pattern, it seems!  ;-}  I have two almost identical
macros, but which also take an optional "where am I?" parameter:

    ;;; A sometimes-helpful macro for debugging.
    (defmacro dbgv ((&optional (where "Unknown Location")) &rest forms)
      `(progn
	 (format t "~&DBGV: @~a:~%" ',where)
	 ,@(loop for form in forms collect
	   `(format t "~a = ~s~%" ',form ,form))))
				    
    ;;; HTML version of DBGV.
    (defmacro dbgvht ((&optional (where "Unknown Location")) &rest forms)
      `(progn
	 (format t "~&<br>DBGV: At ~a<br>~%" ',where)
	 ,@(loop for form in forms collect
	   `(format t "&nbsp;&nbsp;&nbsp;~a = ~s<br>~%" ',form ,form))))

DBGV stands for "DeBuG Values", and DBGVHT (should it have been called
"DBGV/HT"?) is the same, but for use when debugging dynamic web pages.

+---------------
| DISPLAY
| CL-USER> (let ((a 2) (b 4))
|   (let ((c (+ a b)))
|     (display a b c *package* MOST-POSITIVE-FIXNUM)
|     c))
| A: 2
| B: 4
| C: 6
| *PACKAGE*: #<PACKAGE COMMON-LISP-USER>
| MOST-POSITIVE-FIXNUM: 281474976710655
| 
| 6
| CL-USER> 
+---------------

    > (let ((a 2) (b 4))
        (let ((c (+ a b)))
          (dbgv (nested-let) a b c *package* most-positive-fixnum)
          c))
    DBGV: @NESTED-LET:
    A = 2
    B = 4
    C = 6
    *PACKAGE* = #<The COMMON-LISP-USER package, 114/192 internal, 0/9 external>
    MOST-POSITIVE-FIXNUM = 536870911
    6
    > 
    > (let ((a 2) (b 4))
        (let ((c (+ a b)))
          (dbgvht (nested-let-in-a-web-page)
	    a b c *package* most-positive-fixnum)
          c))
    <br>DBGV: At NESTED-LET-IN-A-WEB-PAGE<br>
    &nbsp;&nbsp;&nbsp;A = 2<br>
    &nbsp;&nbsp;&nbsp;B = 4<br>
    &nbsp;&nbsp;&nbsp;C = 6<br>
    &nbsp;&nbsp;&nbsp;*PACKAGE* = #<The COMMON-LISP-USER package, 115/192 internal, 0/9 external><br>
    &nbsp;&nbsp;&nbsp;MOST-POSITIVE-FIXNUM = 536870911<br>
    6
    > 

But note that even with your version the "SYMBOLS" don't actually
have to be just symbols -- arbitrary forms work just fine, too:

    > (let ((a 2) (b 4))
        (let ((c (+ a b)))
          (dbgv ()
	    a b c
	    (+ a b)
	    (eql c (+ a b)))))
    DBGV: @Unknown Location:
    A = 2
    B = 4
    C = 6
    (+ A B) = 6
    (EQL C (+ A B)) = T
    NIL
    > 

Sometimes I find that useful.


-Rob

p.s. Hmmm... Now that I know FORMAT a bit better than when I first
wrote DBGV, maybe it should be defined this way:  ;-}  ;-}

    (defmacro dbgv ((&optional (where "Unknown Location")) &rest forms)
      `(format t "~&DBGV: @~a:~%~:{~a = ~s~%~}"
		 ',where
	         (list ,@(loop for form in forms collect
		          `(list ',form ,form)))))

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607