From: Mirko
Subject: macroexpansion complains about undefined symbol - can't see why
Date: 
Message-ID: <abe6432f-7c27-4acb-bb7b-2ab0c0436e5b@i6g2000yqj.googlegroups.com>
I must be missing something obvious.  Consider the following macro

(defmacro dostring ((item string &optional return counter) &body body)
  "Perform `read-from-string's on string, execute `body' and
optionally return `return'.  To count the number of processed items,
use `counter' "
  (with-gensyms (start item%)
    `(let ((,start 0)
	   (,item nil)
	   (,item% nil))
       (do (,@(if counter `((,counter 0 (incf ,counter))))
	      (,item (progn
		       (multiple-value-setq (,item% ,start)
			 (read-from-string ,string nil 'end :start ,start))
		       ,item%)
		     (progn
		       (multiple-value-setq (,item% ,start)
			 (read-from-string ,string nil 'end :start ,start))
		       ,item%)))
	   ((eq ,item 'end) ,return)
	 ,@body))))

Why does it report that `item' is undefined?

Usage example:

(dostring (item "a b c" i i)
  (print i)
  (format t "i: ~d, item: ~a~%" i item))

Thanks,

Mirko

From: Joshua Taylor
Subject: Re: macroexpansion complains about undefined symbol - can't see why
Date: 
Message-ID: <h37kqm$5fd$1@news.eternal-september.org>
Mirko wrote:
> I must be missing something obvious.  Consider the following macro
> 
> (defmacro dostring ((item string &optional return counter) &body body)
>   "Perform `read-from-string's on string, execute `body' and
> optionally return `return'.  To count the number of processed items,
> use `counter' "
>   (with-gensyms (start item%)
>     `(let ((,start 0)
> 	   (,item nil)
> 	   (,item% nil))
>        (do (,@(if counter `((,counter 0 (incf ,counter))))
> 	      (,item (progn
> 		       (multiple-value-setq (,item% ,start)
> 			 (read-from-string ,string nil 'end :start ,start))
> 		       ,item%)
> 		     (progn
> 		       (multiple-value-setq (,item% ,start)
> 			 (read-from-string ,string nil 'end :start ,start))
> 		       ,item%)))
> 	   ((eq ,item 'end) ,return)
> 	 ,@body))))
> 
> Why does it report that `item' is undefined?
> 
> Usage example:
> 
> (dostring (item "a b c" i i)
>   (print i)
>   (format t "i: ~d, item: ~a~%" i item))
> 
> Thanks,
> 
> Mirko

Under LispWorks, I see a "bound but not referenced" warning.  DO 
establishes a binding, and so the enclosing LET's binding is never 
referenced:

CL-USER> (defun ds ()
               (dostring (item "a b c" i i)
                 (print i)
                 (format t "i: ~d, item: ~a~%" i item)))
DS

CL-USER> (compile 'ds)
;;;*** Warning in DS: ITEM is bound but not referenced
DS
((NIL #<CONDITIONS::SIMPLE-STYLE-WARNING 200D5C8B>))
NIL

CL-USER>
(pprint (macroexpand-1 '(dostring (item "a b c" i i)
                           (print i)
                           (format t "i: ~d, item: ~a~%" i item))))

(LET ((#:START10026 0) (ITEM NIL) (#:ITEM%10027 NIL))
                        ^^^^^^^^^^ ; bound but not referenced
   (DO ((I 0 (INCF I))
        (ITEM
         ^^^^ ; bound and referenced
    ...

//JT
From: Mirko
Subject: Re: macroexpansion complains about undefined symbol - can't see why
Date: 
Message-ID: <2637fd84-c2ef-4ae3-a88e-f64362cded42@s31g2000yqs.googlegroups.com>
On Jul 10, 10:51 am, Joshua Taylor <······@cs.rpi.edu> wrote:
> Mirko wrote:
> > I must be missing something obvious.  Consider the following macro
>
> > (defmacro dostring ((item string &optional return counter) &body body)
> >   "Perform `read-from-string's on string, execute `body' and
> > optionally return `return'.  To count the number of processed items,
> > use `counter' "
> >   (with-gensyms (start item%)
> >     `(let ((,start 0)
> >       (,item nil)
> >       (,item% nil))
> >        (do (,@(if counter `((,counter 0 (incf ,counter))))
> >          (,item (progn
> >                   (multiple-value-setq (,item% ,start)
> >                     (read-from-string ,string nil 'end :start ,start))
> >                   ,item%)
> >                 (progn
> >                   (multiple-value-setq (,item% ,start)
> >                     (read-from-string ,string nil 'end :start ,start))
> >                   ,item%)))
> >       ((eq ,item 'end) ,return)
> >     ,@body))))
>
> > Why does it report that `item' is undefined?
>
> > Usage example:
>
> > (dostring (item "a b c" i i)
> >   (print i)
> >   (format t "i: ~d, item: ~a~%" i item))
>
> > Thanks,
>
> > Mirko
>
> Under LispWorks, I see a "bound but not referenced" warning.  DO
> establishes a binding, and so the enclosing LET's binding is never
> referenced:
>
> CL-USER> (defun ds ()
>                (dostring (item "a b c" i i)
>                  (print i)
>                  (format t "i: ~d, item: ~a~%" i item)))
> DS
>
> CL-USER> (compile 'ds)
> ;;;*** Warning in DS: ITEM is bound but not referenced
> DS
> ((NIL #<CONDITIONS::SIMPLE-STYLE-WARNING 200D5C8B>))
> NIL
>
> CL-USER>
> (pprint (macroexpand-1 '(dostring (item "a b c" i i)
>                            (print i)
>                            (format t "i: ~d, item: ~a~%" i item))))
>
> (LET ((#:START10026 0) (ITEM NIL) (#:ITEM%10027 NIL))
>                         ^^^^^^^^^^ ; bound but not referenced
>    (DO ((I 0 (INCF I))
>         (ITEM
>          ^^^^ ; bound and referenced
>     ...
>
> //JT

aaargh!

You were right.  The (let ((item ...))) was a leftover from a previous
iteration of the code.

Thanks to both for looking into this.

Mirko
From: Pascal J. Bourguignon
Subject: Re: macroexpansion complains about undefined symbol - can't see why
Date: 
Message-ID: <7cfxd4sidu.fsf@pbourguignon.anevia.com>
Mirko <·············@gmail.com> writes:

> I must be missing something obvious.  Consider the following macro
>
> (defmacro dostring ((item string &optional return counter) &body body)
>   "Perform `read-from-string's on string, execute `body' and
> optionally return `return'.  To count the number of processed items,
> use `counter' "
>   (with-gensyms (start item%)
>     `(let ((,start 0)
> 	   (,item nil)
> 	   (,item% nil))
>        (do (,@(if counter `((,counter 0 (incf ,counter))))
> 	      (,item (progn
> 		       (multiple-value-setq (,item% ,start)
> 			 (read-from-string ,string nil 'end :start ,start))
> 		       ,item%)
> 		     (progn
> 		       (multiple-value-setq (,item% ,start)
> 			 (read-from-string ,string nil 'end :start ,start))
> 		       ,item%)))
> 	   ((eq ,item 'end) ,return)
> 	 ,@body))))
>
> Why does it report that `item' is undefined?
>
> Usage example:
>
> (dostring (item "a b c" i i)
>   (print i)
>   (format t "i: ~d, item: ~a~%" i item))
>
> Thanks,
>
> Mirko


So do I.


C/USER[6]> (defmacro dostring ((item string &optional return counter) &body body)
             "Perform `read-from-string's on string, execute `body' and
optionally return `return'.  To count the number of processed items,
use `counter' "
             (with-gensyms (start item%)
               `(let ((,start 0)
                      (,item nil)
                      (,item% nil))
                  (do (,@(if counter `((,counter 0 (incf ,counter))))
                         (,item (progn
                                  (multiple-value-setq (,item% ,start)
                                    (read-from-string ,string nil 'end :start ,start))
                                  ,item%)
                                (progn
                                  (multiple-value-setq (,item% ,start)
                                    (read-from-string ,string nil 'end :start ,start))
                                  ,item%)))
                      ((eq ,item 'end) ,return)
                    ,@body))))
DOSTRING
C/USER[7]> (macroexpand '(dostring (item "a b c" i i)
                          (print i)
                          (format t "i: ~d, item: ~a~%" i item)))
(LET ((#1=#:START9995 0) (ITEM NIL) (#2=#:ITEM%9996 NIL))
 (DO
  ((I 0 (INCF I))
   (ITEM
    (PROGN (MULTIPLE-VALUE-SETQ (#2# #1#) (READ-FROM-STRING #3="a b c" NIL 'END :START #1#)) #2#)
    (PROGN (MULTIPLE-VALUE-SETQ (#2# #1#) (READ-FROM-STRING #3# NIL 'END :START #1#)) #2#)))
  ((EQ ITEM 'END) I) (PRINT I) (FORMAT T "i: ~d, item: ~a~%" I ITEM))) ;
T
C/USER[8]> (dostring (item "a b c" i i)
                     (print i)
                     (format t "i: ~d, item: ~a~%" i item))

0 i: 0, item: A

1 i: 1, item: B

2 i: 2, item: C
3
C/USER[9]> 


Perhaps you've got a problem with with-gensyms?
I use this definition:


#-:with-debug-gensym
(DEFMACRO WITH-GENSYMS (SYMS &BODY BODY)
  "
DO:      Replaces given symbols with gensyms. Useful for creating macros.
NOTE:    This version by Paul Graham in On Lisp."
  `(LET ,(MAPCAR (LAMBDA (S) `(,S (GENSYM ,(string s)))) SYMS) ,@BODY))


#+:with-debug-gensym
(defpackage "COM.INFORMATIMAGO.GENSYMS" (:USE))
#+:with-debug-gensym
(DEFMACRO WITH-GENSYMS (SYMS &BODY BODY)
  "
DO:      Replaces given symbols with gensyms. Useful for creating macros.
NOTE:    This version by Paul Graham in On Lisp."
  `(LET ,(MAPCAR
          (LAMBDA (S) `(,S (INTERN (STRING (GENSYM ,(string s)))
                                   "COM.INFORMATIMAGO.GENSYMS"))) SYMS) ,@BODY))



PS: What about:

C/USER[9]> (dostring (item "begin and end are words" i i) (print (list i item)))

(0 BEGIN) 
(1 AND) 
2

???


-- 
__Pascal Bourguignon__
From: Kaz Kylheku
Subject: Re: macroexpansion complains about undefined symbol - can't see why
Date: 
Message-ID: <20090725040452.623@gmail.com>
On 2009-07-10, Mirko <·············@gmail.com> wrote:
> I must be missing something obvious.  Consider the following macro
>
> (defmacro dostring ((item string &optional return counter) &body body)

[ snip ]

> Usage example:
>
> (dostring (item "a b c" i i)
>   (print i)
>   (format t "i: ~d, item: ~a~%" i item))

Also, here is an idea: when you're testing macros that take symbols as
arguments, use different symbols in the test code. If the above expression
results in a complaint about ITEM, is it complaining about the ITEM argument
expression? Or is it complaining about the ITEM symbol that is internal in your
macro?