From: deech
Subject: Newbie: Inserting Debug Statements into Lisp Code
Date: 
Message-ID: <095cc5d3-9636-44b7-9e5d-b5b59fd09dfa@z66g2000hsc.googlegroups.com>
Is there a convenient way of inserting debug/format statements into a
form that does not sequence its statements like progn? For example,

(cond (cond1) (do-action-A some-variable)
          (cond2) (do-action-B some-other-variable)
          t            (default-action))


So let's say that do-action-A is not behaving correctly because some-
variable has an unexpected value. The only way I know to observe the
value of the variable before do-action-A is invoked is with a format
statement. And to do that I have to rip apart my cond into this:

(cond (cond1) (progn
                          (format t "Variable: ~a" some-variable)
                          (do-action-A some-variable))
          (cond2) (do-action-B some-other-variable)
           t           (default-action))

Is there an easier way in general to do things like this? Or is this
approach wrong in Lisp?

-Deech

From: Rob St. Amant
Subject: Re: Newbie: Inserting Debug Statements into Lisp Code
Date: 
Message-ID: <g30ung$871$1@blackhelicopter.databasix.com>
deech <············@gmail.com> writes:

> Is there a convenient way of inserting debug/format statements into a
> form that does not sequence its statements like progn? For example,
>
> (cond (cond1) (do-action-A some-variable)
>           (cond2) (do-action-B some-other-variable)
>           t            (default-action))
>
>
> So let's say that do-action-A is not behaving correctly because some-
> variable has an unexpected value. The only way I know to observe the
> value of the variable before do-action-A is invoked is with a format
> statement. And to do that I have to rip apart my cond into this:
>
> (cond (cond1) (progn
>                           (format t "Variable: ~a" some-variable)
>                           (do-action-A some-variable))
>           (cond2) (do-action-B some-other-variable)
>            t           (default-action))
>
> Is there an easier way in general to do things like this? Or is this
> approach wrong in Lisp?

In addition to the other responses, consider simply using print (or
spy, a utility macro that should be easy to find or define).  You can
use it for situations like this:

(if (do-action-A some-variable) ...

If you don't want

(if (progn (format t "Variable: ~a" some-variable)
           (do-action-A some-variable)) ...

then write

(if (do-action-A (print some-variable))...

or 

(if (do-action-A (spy some-variable))...
From: Carl Taylor
Subject: Re: Newbie: Inserting Debug Statements into Lisp Code
Date: 
Message-ID: <xWS4k.44733$102.941@bgtnsc05-news.ops.worldnet.att.net>
"deech" <············@gmail.com> wrote in message 
·········································@z66g2000hsc.googlegroups.com...
> Is there a convenient way of inserting debug/format statements into a
> form that does not sequence its statements like progn? For example,
>
> (cond (cond1) (do-action-A some-variable)
>          (cond2) (do-action-B some-other-variable)
>          t            (default-action))
>
>
> So let's say that do-action-A is not behaving correctly because some-
> variable has an unexpected value. The only way I know to observe the
> value of the variable before do-action-A is invoked is with a format
> statement. And to do that I have to rip apart my cond into this:
>
> (cond (cond1) (progn
>                          (format t "Variable: ~a" some-variable)
>                          (do-action-A some-variable))
>          (cond2) (do-action-B some-other-variable)
>           t           (default-action))
>
> Is there an easier way in general to do things like this? Or is this
> approach wrong in Lisp?


You don't need to use progn.  A cond condition clause can contain as 
many forms as you want, but only the last is returned.

CL-USER 16 >

(let ((x (svref #(5  6.123  'foo) (random 3))))
  (cond ((integerp x) (print "x is an integer") (print "wow") (+ x x x))
           ((floatp x) (print "x is a float") (print "double-wow") (* x 
pi))
            (t
             (print (list x '???)))))

"x is a float"
"double-wow"
19.235972273330848D0


Carl Taylor
From: Pascal J. Bourguignon
Subject: Re: Newbie: Inserting Debug Statements into Lisp Code
Date: 
Message-ID: <8763sc6j5a.fsf@hubble.informatimago.com>
deech <············@gmail.com> writes:

> Is there a convenient way of inserting debug/format statements into a
> form that does not sequence its statements like progn? For example,
>
> (cond (cond1) (do-action-A some-variable)
>           (cond2) (do-action-B some-other-variable)
>           t            (default-action))
>
>
> So let's say that do-action-A is not behaving correctly because some-
> variable has an unexpected value. The only way I know to observe the
> value of the variable before do-action-A is invoked is with a format
> statement. And to do that I have to rip apart my cond into this:
>
> (cond (cond1) (progn
>                           (format t "Variable: ~a" some-variable)
>                           (do-action-A some-variable))
>           (cond2) (do-action-B some-other-variable)
>            t           (default-action))
>
> Is there an easier way in general to do things like this? Or is this
> approach wrong in Lisp?

What kind of lisp do you use?

In all the lisp I know, COND forms are written:

(cond
  (cond1  
      (do-action-a some-variable))
  (cond2  
      (do-action-b some-variable))
  (t  
      (default-action)))


and therefore there is no problem in adding debugging forms:

(cond
  (cond1  
      (format t "Variable: ~a" some-variable)
      (do-action-a some-variable))
  (cond2  
      (do-action-b some-variable))
  (t  
      (default-action)))


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

PLEASE NOTE: Some quantum physics theories suggest that when the
consumer is not directly observing this product, it may cease to
exist or will exist only in a vague and undetermined state.
From: John Thingstad
Subject: Re: Newbie: Inserting Debug Statements into Lisp Code
Date: 
Message-ID: <op.ucq30ykout4oq5@pandora.alfanett.no>
P� Sat, 14 Jun 2008 18:13:51 +0200, skrev deech <············@gmail.com>:

> Is there a convenient way of inserting debug/format statements into a
> form that does not sequence its statements like progn? For example,
>
> (cond (cond1) (do-action-A some-variable)
>           (cond2) (do-action-B some-other-variable)
>           t            (default-action))
>
>
> So let's say that do-action-A is not behaving correctly because some-
> variable has an unexpected value. The only way I know to observe the
> value of the variable before do-action-A is invoked is with a format
> statement. And to do that I have to rip apart my cond into this:
>
> (cond (cond1) (progn
>                           (format t "Variable: ~a" some-variable)
>                           (do-action-A some-variable))
>           (cond2) (do-action-B some-other-variable)
>            t           (default-action))
>
> Is there an easier way in general to do things like this? Or is this
> approach wrong in Lisp?
>
> -Deech

Well most Lisp's have a system to thunk functions to provide  
trace/debug/profile support.
In LispWorks I find defadvice is handy. Like defmethod it has :before  
:after :around modifiers.
I can insert them for debugging and remove them afterwards..
(defadvice, delete-advice)

If I need to debug a particular statement I set a breakpoint there. This  
allows me to view the stack and all thus the variables.
(Note that that cond is a macro. So to set a breakpoint in front of a cond  
use (break))
I can also run statements in that stack frame and modify values and then  
resume.
You can automate this with handler-case, restart-bind, invoke-restart.  
(see PCL)

--------------
John Thingstad
From: deech
Subject: Re: Newbie: Inserting Debug Statements into Lisp Code
Date: 
Message-ID: <9234f69f-23e7-4d84-83f0-c8170c0880eb@l42g2000hsc.googlegroups.com>
Thanks for the responses. I didn't know about (print some-variable)
and spy-thanks Carl, I'll definitely check those out. Pascal, COND was
a really bad example. I should have used a simple IF statement lie:

(if (some-predicate)
    (do-stuff)
    (do-other-stuff))

This is where I usually run into problems because some-predicate,do-
stuff and do-other-stuff do not accept more than one sequence.

-Deech


John Thingstad wrote:
> P� Sat, 14 Jun 2008 18:13:51 +0200, skrev deech <············@gmail.com>:
>
> > Is there a convenient way of inserting debug/format statements into a
> > form that does not sequence its statements like progn? For example,
> >
> > (cond (cond1) (do-action-A some-variable)
> >           (cond2) (do-action-B some-other-variable)
> >           t            (default-action))
> >
> >
> > So let's say that do-action-A is not behaving correctly because some-
> > variable has an unexpected value. The only way I know to observe the
> > value of the variable before do-action-A is invoked is with a format
> > statement. And to do that I have to rip apart my cond into this:
> >
> > (cond (cond1) (progn
> >                           (format t "Variable: ~a" some-variable)
> >                           (do-action-A some-variable))
> >           (cond2) (do-action-B some-other-variable)
> >            t           (default-action))
> >
> > Is there an easier way in general to do things like this? Or is this
> > approach wrong in Lisp?
> >
> > -Deech
>
> Well most Lisp's have a system to thunk functions to provide
> trace/debug/profile support.
> In LispWorks I find defadvice is handy. Like defmethod it has :before
> :after :around modifiers.
> I can insert them for debugging and remove them afterwards..
> (defadvice, delete-advice)
>
> If I need to debug a particular statement I set a breakpoint there. This
> allows me to view the stack and all thus the variables.
> (Note that that cond is a macro. So to set a breakpoint in front of a cond
> use (break))
> I can also run statements in that stack frame and modify values and then
> resume.
> You can automate this with handler-case, restart-bind, invoke-restart.
> (see PCL)
>
> --------------
> John Thingstad
From: Thomas A. Russ
Subject: Re: Newbie: Inserting Debug Statements into Lisp Code
Date: 
Message-ID: <ymi3andrwwr.fsf@blackcat.isi.edu>
deech <············@gmail.com> writes:

> Thanks for the responses. I didn't know about (print some-variable)
> and spy-thanks Carl, I'll definitely check those out. Pascal, COND was
> a really bad example. I should have used a simple IF statement lie:
> 
> (if (some-predicate)
>     (do-stuff)
>     (do-other-stuff))
> 
> This is where I usually run into problems because some-predicate,do-
> stuff and do-other-stuff do not accept more than one sequence.

This is a fair issue to raise.

The simplest method of finding out what is going on is to use the TRACE
macro on the function that is being called.  This doesn't require any
changes to your source code.

Of course, if it is a fairly widely used function, then you may get too
much output and may need to resort to inserting debugging print
statements.

Normally you would then just bite the bullet and also include the progn
statements, but if this is unappealing to you, you could always create a
macro that does what you want.  You would still be adding a form AROUND
the form you wanted to call, but you can make this actually add some
other useful features, and learn a bit about macro programming to boot.

Consider:

(defmacro debug-values ((&rest vars) &body body)
  (let* ((format-args nil)  ;; Set below
         (format-string
           (with-output-to-string (s)
             (setq format-args
                   (loop for v in vars
                         when (stringp v)
                         do (write-string v s)
                         else do (format s " ~A = ~~A  " v)
                              and collect v)))))
      `(progn 
         (format *trace-output* ,format-string ,@format-args)
         ,@body)))

(defun f (x y)
  (debug-values (x y)
    (+ (* 2 x) y)))

(defun g (x y)
  (debug-values ("Function g:" (* 2 x) " the next item should be negative!" y)
    (+ (* 2 x) y)))


Examples:

CL-USER> (f 2 3)
 X = 2   Y = 3  
7

CL-USER> (g 2 3)
Function g: (* 2 X) = 4   the next item should be negative! Y = 3  
7


-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: gutzofter
Subject: Re: Newbie: Inserting Debug Statements into Lisp Code
Date: 
Message-ID: <e17c8544-f007-41e5-b424-e9e5ffe425e9@v26g2000prm.googlegroups.com>
Do you not use any type of unit test?

How come you're letting some variable get into this state?

Shouldn't you be debugging the function that generates some-variable?
From: Peter Hildebrandt
Subject: Re: Newbie: Inserting Debug Statements into Lisp Code
Date: 
Message-ID: <4854d2aa$0$90264$14726298@news.sunsite.dk>
deech wrote:
> Is there a convenient way of inserting debug/format statements into a
> form that does not sequence its statements like progn? For example,

If you use cells, you will have the utils-kt package with trc, eko, and 
friends.  So you could use (eko "do-action" (do-action x)), which 
returns the result of do-action and prints something like do-action ==> 5

trc is for printing: (trc "currently the params are" x y z), wtrc helps 
debugging nested funcalls:

(wtrc (1 50 "entering block 1")
    (do-something))

Any calls to trc from within the wtrc block are preceeded by as many 
dots as there are nested wtrc blocks.  1 is the min depth, 50 max (so 
wtrc breaks on recursion deeper than that)

Peter

> 
> (cond (cond1) (do-action-A some-variable)
>           (cond2) (do-action-B some-other-variable)
>           t            (default-action))
> 
> 
> So let's say that do-action-A is not behaving correctly because some-
> variable has an unexpected value. The only way I know to observe the
> value of the variable before do-action-A is invoked is with a format
> statement. And to do that I have to rip apart my cond into this:
> 
> (cond (cond1) (progn
>                           (format t "Variable: ~a" some-variable)
>                           (do-action-A some-variable))
>           (cond2) (do-action-B some-other-variable)
>            t           (default-action))
> 
> Is there an easier way in general to do things like this? Or is this
> approach wrong in Lisp?
> 
> -Deech
From: Kenny
Subject: Re: Newbie: Inserting Debug Statements into Lisp Code
Date: 
Message-ID: <48550973$0$7328$607ed4bc@cv.net>
Peter Hildebrandt wrote:
> deech wrote:
>> Is there a convenient way of inserting debug/format statements into a
>> form that does not sequence its statements like progn? For example,
> 
> If you use cells, you will have the utils-kt package with trc, eko, and 
> friends.  So you could use (eko "do-action" (do-action x)), which 
> returns the result of do-action and prints something like do-action ==> 5

Not bad, but that is the syntax I started from, cooked up by a 
subordinate on the CliniSys project. I wanted to see even more info, so 
I extended what we see above to:

    (eko ("hi mon" var-1 var-2) (the-original-form 42))

This however requires an extra set of parens. if I can do without extra 
info like var-1 and var-2 above, we can just sneak in inside the 
existing parens:

   (ekx hi-mom the-original-form 42)

Had I been cleverer I would have done:

   (ekx hi-mom var-1 var-2 /ekx the-original-form 42)

Left as an exercise. one important feature, btw, is having the option of 
leaving an eko in place for future use yet disabling it once an 
immediate crisis has passed:

   (eko (nil "himom" v1 v2) (t-o-form 42))


...expands simply to (t-o-form 42) just in case v1 or v2 was actually an 
expensive function call. Nothing like that was done with ekx because it 
is so easy to insert we can just toss them when done, or convert to eko 
if we think we will need them again.



> 
> trc is for printing: (trc "currently the params are" x y z),

trcx is fun. (trcx hi-mom v1 v2) expands to:

    (trc "hi-mom" :v1 v1 :v2 v2)

useful with a lot of values to dump.

But EKX extended to support /ekx (and maybe the trick of disabling it 
with a leading nil) seems ideal for the OP.

kt

>... wtrc helps 
> debugging nested funcalls:
> 
> (wtrc (1 50 "entering block 1")
>    (do-something))
> 
> Any calls to trc from within the wtrc block are preceeded by as many 
> dots as there are nested wtrc blocks.  1 is the min depth, 50 max (so 
> wtrc breaks on recursion deeper than that)
> 
> Peter
> 
>>
>> (cond (cond1) (do-action-A some-variable)
>>           (cond2) (do-action-B some-other-variable)
>>           t            (default-action))
>>
>>
>> So let's say that do-action-A is not behaving correctly because some-
>> variable has an unexpected value. The only way I know to observe the
>> value of the variable before do-action-A is invoked is with a format
>> statement. And to do that I have to rip apart my cond into this:
>>
>> (cond (cond1) (progn
>>                           (format t "Variable: ~a" some-variable)
>>                           (do-action-A some-variable))
>>           (cond2) (do-action-B some-other-variable)
>>            t           (default-action))
>>
>> Is there an easier way in general to do things like this? Or is this
>> approach wrong in Lisp?
>>
>> -Deech
From: Kenny
Subject: Re: Newbie: Inserting Debug Statements into Lisp Code
Date: 
Message-ID: <48550d4c$0$7329$607ed4bc@cv.net>
Kenny wrote:
> Peter Hildebrandt wrote:
>> deech wrote:
>>> Is there a convenient way of inserting debug/format statements into a
>>> form that does not sequence its statements like progn? For example,
>>
>> If you use cells, you will have the utils-kt package with trc, eko, 
>> and friends.  So you could use (eko "do-action" (do-action x)), which 
>> returns the result of do-action and prints something like do-action ==> 5
> 
> Not bad, but that is the syntax I started from, cooked up by a 
> subordinate on the CliniSys project. I wanted to see even more info, so 
> I extended what we see above to:
> 
>    (eko ("hi mon" var-1 var-2) (the-original-form 42))
> 
> This however requires an extra set of parens. if I can do without extra 
> info like var-1 and var-2 above, we can just sneak in inside the 
> existing parens:
> 
>   (ekx hi-mom the-original-form 42)
> 
> Had I been cleverer I would have done:
> 
>   (ekx hi-mom var-1 var-2 /ekx the-original-form 42)
> 
> Left as an exercise. one important feature, btw, is having the option of 
> leaving an eko in place for future use yet disabling it once an 
> immediate crisis has passed:
> 
>   (eko (nil "himom" v1 v2) (t-o-form 42))
> 
> 
> ...expands simply to (t-o-form 42) just in case v1 or v2 was actually an 
> expensive function call. Nothing like that was done with ekx because it 
> is so easy to insert we can just toss them when done, or convert to eko 
> if we think we will need them again.
> 
> 
> 
>>
>> trc is for printing: (trc "currently the params are" x y z),
> 
> trcx is fun. (trcx hi-mom v1 v2) expands to:
> 
>    (trc "hi-mom" :v1 v1 :v2 v2)
> 
> useful with a lot of values to dump.

Not so useful when the values are actually (big-long-forms-like 42). :)

One other trick. The trc macro looks specifically for a string or the 
the sybol nil at macro-expansion time. If it gets something else:

    (trc x "whaddya know" 42)

...the expansion is something like:

    (when (trcp x)
       ...normal expansion)

ie, conditional output by providing a method for the trcp GF, which 
defaults to t.

kt


> 
> But EKX extended to support /ekx (and maybe the trick of disabling it 
> with a leading nil) seems ideal for the OP.
> 
> kt
> 
>> ... wtrc helps debugging nested funcalls:
>>
>> (wtrc (1 50 "entering block 1")
>>    (do-something))
>>
>> Any calls to trc from within the wtrc block are preceeded by as many 
>> dots as there are nested wtrc blocks.  1 is the min depth, 50 max (so 
>> wtrc breaks on recursion deeper than that)
>>
>> Peter
>>
>>>
>>> (cond (cond1) (do-action-A some-variable)
>>>           (cond2) (do-action-B some-other-variable)
>>>           t            (default-action))
>>>
>>>
>>> So let's say that do-action-A is not behaving correctly because some-
>>> variable has an unexpected value. The only way I know to observe the
>>> value of the variable before do-action-A is invoked is with a format
>>> statement. And to do that I have to rip apart my cond into this:
>>>
>>> (cond (cond1) (progn
>>>                           (format t "Variable: ~a" some-variable)
>>>                           (do-action-A some-variable))
>>>           (cond2) (do-action-B some-other-variable)
>>>            t           (default-action))
>>>
>>> Is there an easier way in general to do things like this? Or is this
>>> approach wrong in Lisp?
>>>
>>> -Deech
From: ·············@gmail.com
Subject: Re: Newbie: Inserting Debug Statements into Lisp Code
Date: 
Message-ID: <c89f845c-30c6-4034-9836-3587721bf236@m44g2000hsc.googlegroups.com>
On Jun 14, 12:13 pm, deech <············@gmail.com> wrote:
> Is there a convenient way of inserting debug/format statements into a
> form that does not sequence its statements like progn? For example,
>
> (cond (cond1) (do-action-A some-variable)
>           (cond2) (do-action-B some-other-variable)
>           t            (default-action))
>
> So let's say that do-action-A is not behaving correctly because some-
> variable has an unexpected value. The only way I know to observe the
> value of the variable before do-action-A is invoked is with a format
> statement. And to do that I have to rip apart my cond into this:
>
> (cond (cond1) (progn
>                           (format t "Variable: ~a" some-variable)
>                           (do-action-A some-variable))
>           (cond2) (do-action-B some-other-variable)
>            t           (default-action))
>
> Is there an easier way in general to do things like this? Or is this
> approach wrong in Lisp?
>
> -Deech

There was a discussion on debugging in CL the following thread: " How
to debug in Common Lisp?"  It was going on this January.

Mirko
From: Daniel Weinreb
Subject: Re: Newbie: Inserting Debug Statements into Lisp Code
Date: 
Message-ID: <485BA614.5080807@alum.mit.edu>
deech wrote:
> Is there a convenient way of inserting debug/format statements into a
> form that does not sequence its statements like progn? 

Yeah, it's a bit of a pain in the neck.  As people said, writing
a little macro can help.  Don't forget that your function might
return multiple values, so to get this REALLY right, make sure
that you propagate back the multiple values.  Easy if the
print statement is before the form, but it takes a little
bit of work if the print statement is after.  prog1 is
useful here.
From: Pascal J. Bourguignon
Subject: Re: Newbie: Inserting Debug Statements into Lisp Code
Date: 
Message-ID: <7cfxr8p8yh.fsf@pbourguignon.anevia.com>
Daniel Weinreb <···@alum.mit.edu> writes:

> deech wrote:
>> Is there a convenient way of inserting debug/format statements into a
>> form that does not sequence its statements like progn? 
>
> Yeah, it's a bit of a pain in the neck.  As people said, writing
> a little macro can help.  Don't forget that your function might
> return multiple values, so to get this REALLY right, make sure
> that you propagate back the multiple values.  Easy if the
> print statement is before the form, but it takes a little
> bit of work if the print statement is after.  prog1 is
> useful here.

MULTIPLE-VALUE-PROG1

prog1 is actually 1�: it returns the first value of the first form.

-- 
__Pascal Bourguignon__
From: Juho Snellman
Subject: Re: Newbie: Inserting Debug Statements into Lisp Code
Date: 
Message-ID: <87fxr8p8u9.fsf@vasara.proghammer.com>
Daniel Weinreb <···@alum.mit.edu> writes:

> deech wrote:
> > Is there a convenient way of inserting debug/format statements into a
> > form that does not sequence its statements like progn?
> 
> Yeah, it's a bit of a pain in the neck.  As people said, writing
> a little macro can help.  Don't forget that your function might
> return multiple values, so to get this REALLY right, make sure
> that you propagate back the multiple values.  Easy if the
> print statement is before the form, but it takes a little
> bit of work if the print statement is after.  prog1 is
> useful here.

Annoyingly PROG1 isn't useful there, you need MULTIPLE-VALUE-PROG1.
(I wonder whether specifying PROG1 to work like that was for backwards
compability, or just a premature optimization attempt in the spec, or
for some other reason).

-- 
Juho Snellman