[plt-scheme] Help with a macro

From: Evan Farrer (farrer at cs.utah.edu)
Date: Mon Oct 3 11:08:36 EDT 2005

Thanks Jay for a solution that works.  As for the suggestion that for this example it would be better to let the programmer provide the identifier, I completely agree.  I was trying to provide a simple example that demonstrates the behavior that I'm seeing.  I appreciate the priciple being spelled out as I'd hate for someone to use my toy example as "good practice".  

I'm still curious a to why the macro that I wrote doesn't work.  Could someone give me an explanation?  When I run it under the expander language it appears that the introduced "it" identifier is being bound to 9, 8, 7, ... but the output suggests otherwise.  At this point I'm more interested in fixing my thinking than in fixing my macro.

Thanks,

Evan

On Mon, Oct 03, 2005 at 03:26:27PM +0100, Matt Jadud wrote:
> Hi Evan,
> 
> While this does not address your question, you are trying to do 
> something I've tried to eliminate from my macro-fu, which is the 
> introduction of new identifiers into the macro's scope. It is, generally 
> speaking, easier to let the programmer provide the identifier.
> 
> For example, you could compress your macro quite a bit by expanding the 
> loop into, well, a Scheme loop (well, a named 'let', anyway).
> 
> (define-syntax (a-loop-too stx)
>   (syntax-case stx ()
>     [(_ (index count) bodies ...)
>      #`(let loop ([#,(syntax index) #,(syntax count)])
>          (unless (zero? #,(syntax index))
>            #,@(syntax->list (syntax (bodies ...)))
>            (loop (sub1 #,(syntax index)))))]
>     ))
> 
> Note how I've forced the macro writer to provide the loop counter, 
> instead of having the identifier magically "appear" in the context of 
> the macro. This makes it obvious to a programmer using your macro (or to 
> yourself a few days, weeks, or months later) where the counter variable 
> comes from. It also becomes easier to nest the macro as well, as I can say
> 
> (a-loop-too (a 5)
>   (a-loop-too (b 4)
>     (printf "~a ~a~n" a b)))
> 
> and it will work; without the use of "gensym", it is possible you would 
> have collisions on the identifier "it".
> 
> As I said, that doesn't answer your question, but gives you some 
> food-for-thought; my apologies if I'm completely in left-field, or this 
> generally isn't applicable.
> 
> M
> 
> 
> Evan Farrer wrote:
> >I've run into a problem with a macro that I'm writing.  I've come up with 
> >a simple example that demonstrates the behavior that I'm seeing.
> >
> >(define-syntax (a-loop stx)
> >  (syntax-case stx (for)
> >               [(_ count body ...)
> >               (with-syntax ([itid (datum->syntax-object (syntax count) 
> >               'it)])     (let ([done (equal? 0 
> >                            (syntax-object->datum #'count))]
> >                                        [next (sub1 (syntax-object->datum 
> >                                        #'count))])
> >                              #`(let ([itid count])
> >                                  #,(if done
> >                                      #'(begin body ...)
> >                                      #`(begin
> >                                          body ...
> >                                          (_ #,next body ...))))))]))
> >
> >If I call the following like:
> >  (a-loop 9 (printf "~a" it))
> >
> >I get a series of 9's  I'd expect "9876543210".  I've tried running it 
> >under the expander language and from what I can see, everything should be 
> >working.  Can anyone enlighten me as to where my thinking is wrong, and 
> >how this should be implemented?
> >
> >Thanks,
> >
> >Evan
> >  For list-related administrative tasks:
> >  http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>  For list-related administrative tasks:
>  http://list.cs.brown.edu/mailman/listinfo/plt-scheme


Posted on the users mailing list.