From: ken yip
Subject: How to write a macro for printing variable's name and its value
Date: 
Message-ID: <1992Aug7.183403.19252@cs.yale.edu>
I want a macro debug-format  such that

  (debug-format x y)
 
translates into

  (format t "~A = ~A  ~A = ~A" x <value-of-x> y <value-of-y>)

E.g.. (let ((x 3)
            (y 4))
         (debug-format x y))

should print

x = 3   y = 4

The problem is I don't know how to get the value of lexical variables
during a macroexpansion.

Any suggestion?

From: Tim Moore
Subject: Re: How to write a macro for printing variable's name and its value
Date: 
Message-ID: <MOORE.92Aug7125936@defmacro.cs.utah.edu>
In article <·····················@cs.yale.edu> ·······@CS.YALE.EDU (ken yip) writes:
   I want a macro debug-format  such that

     (debug-format x y)

   translates into

     (format t "~A = ~A  ~A = ~A" x <value-of-x> y <value-of-y>)

   E.g.. (let ((x 3)
	       (y 4))
	    (debug-format x y))

   should print

   x = 3   y = 4

   The problem is I don't know how to get the value of lexical variables
   during a macroexpansion.

How about

(defmacro debug-format (&rest vars)
  (let ((vars-and-vals (mapcan #'(lambda (var) `(',var ,var))
			       vars)))
    `(format t "~{~A = ~A ~}~%" (list ,@vars-and-vals))))
--
Tim Moore                    ·····@cs.utah.edu {bellcore,hplabs}!utah-cs!moore
"Wind in my hair - Shifting and drifting - Mechanical music - Adrenaline surge"
	- Rush
From: Len Charest
Subject: Re: How to write a macro for printing variable's name and its value
Date: 
Message-ID: <1992Aug7.201831.23228@jpl-devvax.jpl.nasa.gov>
In article <·····················@cs.yale.edu>, ·······@CS.YALE.EDU (ken yip) writes:
|> 
|> I want a macro debug-format  such that
|>   (debug-format x y)
|> translates into
|>   (format t "~A = ~A  ~A = ~A" x <value-of-x> y <value-of-y>)
|> The problem is I don't know how to get the value of lexical variables
|> during a macroexpansion.
   ^^^^^^^^^^^^^^^^^^^^^^^

Tim Moore (·····@cs.utah.edu) has already posted a solution to writing the macro, but I wanted to point out that your problem is better expressed as "How do I write a macro such that the macroexpanded code uses the values of lexical variables?" The answer of course is simply that the macroexpanded code should not quote the lexical variables. On the other hand, if you want the 'name' of a variable then the macroexpanded code *should* quote the variable. Using your example above, the form
	(debug-format x y)
should expand into
	(format t "~A = ~A  ~A = ~A" 'x x 'y y)

 ..................................................
                                  Len Charest, Jr.
                 JPL Artificial Intelligence Group
                          ·······@aig.jpl.nasa.gov
From: Marty Hall
Subject: Re: How to write a macro for printing variable's name and its value
Date: 
Message-ID: <1992Aug7.202606.20457@aplcen.apl.jhu.edu>
In article <·····················@cs.yale.edu> ·······@CS.YALE.EDU (ken yip) 
writes:
>
>I want a macro debug-format  such that
>  (debug-format x y)
>translates into
>  (format t "~A = ~A  ~A = ~A" x <value-of-x> y <value-of-y>)
>
>E.g.. (let ((x 3)
>            (y 4))
>         (debug-format x y))
>
>should print
>x = 3   y = 4

Since the question seems to be how to get at lexical vars, not how
to generalize to an arbitrary number of args, here's a simple case:

(defmacro debug-format (a b)
  `(format t "~%~S = ~S, ~S = ~S" ',a ,a ',b ,b))

The original posting mentioned something about having trouble getting
the values of lexical vars, so I would guess the problem involved
quoting the var and evaluating it outside, as with something like

(symbol-value ',a)

Remember:

(setq a 5)
(let ((a 6))
  (print (symbol-value 'a)))

Prints 5, not 6. Same with "eval"...

				- Marty
------------------------------
Q: Did you bring your Rollerblades?
A: (catholic-p 'pope)
			- Conversation with Paul McNamee
From: Scott McKay
Subject: How to write a macro for printing variable's name and its value
Date: 
Message-ID: <19920807205843.5.SWM@SUMMER.SCRC.Symbolics.COM>
    Date: Fri, 7 Aug 1992 14:34 EDT
    From: ken yip <·······@cs.yale.edu>


    I want a macro debug-format  such that

      (debug-format x y)
 
    translates into

      (format t "~A = ~A  ~A = ~A" x <value-of-x> y <value-of-y>)

(defmacro debug-format (&rest vars)
  `(format t ··@{~A = ~A ~}" ,@(mapcan #'(lambda (x) `(',x ,x)) vars))) 

    E.g.. (let ((x 3)
		(y 4))
	     (debug-format x y))

    should print

    x = 3   y = 4

    The problem is I don't know how to get the value of lexical variables
    during a macroexpansion.

    Any suggestion?
From: Kent M Pitman
Subject: How to write a macro for printing variable's name and its value
Date: 
Message-ID: <19920807224054.7.KMP@PLANTAIN.SCRC.Symbolics.COM>
You should know better than to rplacd (or mapcan, in this case) a
backquoted structure.  And, btw, I recommend using ~S, not ~A, to 
see the values of variables.  (In some cases, I'd use them for the
names, too, but probably not for debugging.) So:

 (defmacro debug-format (&rest vars)
   `(format t ··@{~A = ~S ~}" ,@(mapcan #'(lambda (x) (list `',x x)) vars)))

As an aside, note that you can also do the following...

 (defmacro debug-format (&rest vars)
   `(format t ,(format nil "~{~A = ~~S ~}" vars) ,@vars))
From: ·······@cc.helsinki.fi
Subject: Re: How to write a macro for printing variable's name and its value
Date: 
Message-ID: <1992Aug10.210734.1@cc.helsinki.fi>
In article <····················@PLANTAIN.SCRC.Symbolics.COM>,
···@stony-brook.scrc.symbolics.com (Kent M Pitman) writes:
> As an aside, note that you can also do the following...
>  (defmacro debug-format (&rest vars)
>    `(format t ,(format nil "~{~A = ~~S ~}" vars) ,@vars))

Let me respectfully suggest that although you could, you shouldn't. 
Consider
  (debug-format ~a) => (format t "~A = ~S " ~a)

Using FORMAT NIL to build a format string should probably go onto the
pitfalls list, despite being highly unlikely to break anything.
__
Pekka P. Pirinen
Harlequin Ltd, once HMS Government deigns to grant me a work permit
(handler-bind ((wetware-error ...)) (post-to-usenet "..."))
From: Barry Margolin
Subject: Formatted output
Date: 
Message-ID: <166h24INNk2g@early-bird.think.com>
In article <··················@cc.helsinki.fi> ·······@cc.helsinki.fi writes:
>Using FORMAT NIL to build a format string should probably go onto the
>pitfalls list, despite being highly unlikely to break anything.

I've seen it break things.  Not with variables containing "~" in them, but
with messages about files.  I remember going into the debugger in Symbolics
Zmacs or Zmail when it was trying to print a message about a file, and it
was a Unix GNU Emacs backup file, with a name like "foo~".

Another gotcha is using an ordinary string as the format string, e.g.:

  (format t string)

rather than

  (format t "~A" string)

I've seen this same mistake made with C printf() and even years ago on
Multics with ioa_().  It's one of those mistakes that people seem bound to
make with control-string-driven formatted I/O.

Perhaps the C++ people have the right idea with their overloadable <<
operator.  For those who don't know, the simple case is

	stream << obj1 << obj2 << obj3

which is parsed and executed as

	(((stream << obj1) << obj2) << obj3)

The convention is that << implementations return the stream, so this
cascading has the intuitive effect.

However, in addition to outputting ordinary objects, you can also output
special marker objects.  These aren't printed to the stream, but instead
change the stream's state.  I don't know the details, but you can do
something like:

	stream "Value is: " << setw(5) << 12.34567

setw(5) returns a "width" object, which indicates that further objects
should be printed in 5-character fields.  This doesn't really fit into the
Lisp style, though, where we like everything to have a printed
representation; i.e. how would you print a width object?
-- 
Barry Margolin
System Manager, Thinking Machines Corp.

······@think.com          {uunet,harvard}!think!barmar
From: Jeff Dalton
Subject: Re: Formatted output
Date: 
Message-ID: <7152@skye.ed.ac.uk>
In article <············@early-bird.think.com> ······@think.com (Barry Margolin) writes:

>  [...] how would you print a width object?

1. As #<width 4 @ 3ffe8>.  (Sorry, coultn't resist.)

2. By having some functions or streams that obeyed format control
   objects and others that didn't.  (Sort of like the way we can
   sometimes get #\newline and sometimes 
   .)

Anyway, objects that change the state of the stream may be a bad idea
just because their effects aren't limited by to a dynamic extent.
From: Richard Duncan
Subject: Re: How to write a macro for printing variable's name and its value
Date: 
Message-ID: <1992Aug10.220319.14763@ait.com>
>    I want a macro debug-format  such that
>
>      (debug-format x y)
> 
>    translates into
>
>      (format t "~A = ~A  ~A = ~A" x <value-of-x> y <value-of-y>)
>
>    Any suggestion?
>


The trick to this macro is that the macro doesn't access the lexical
environment, the EXPANSION does. So, your macro needs to build quoted
forms of the expressions in EXPRS to do the left hand side of the "="


(defmacro debug-print (&rest exprs)
  `(format t
	   "~&~{~s = ~s~^~&~}"
	   (list ,.(mapcan #'(lambda (expr)
			       `(',expr ,expr))
			   exprs))))


(let ((x 10)
      (y "why")
      (z 'zee))
  (debug-print x y z (list x y z)))

X = 10
Y = "why"
Z = ZEE
(LIST X Y Z) = (10 "why" ZEE)
NIL

This code uses the ~{ and ~} format directives but could just as
easily consed up the format string.

Hope this helps...

-- 
Rich Duncan			Black Diamond Software, Inc.
(203)438-3050			127 Wilton Road East
······@bdsw.com			Ridgfield, CT 06877