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
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?