[plt-scheme] Help with a macro
Matthew,
Thanks that gives me what I need.
Evan
On Mon, Oct 03, 2005 at 09:35:13AM -0600, Matthew Flatt wrote:
> At Mon, 3 Oct 2005 07:40:47 -0600, Evan Farrer wrote:
> > (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 ...))))))]))
>
> Expanding to a use of a non-hygienic macro is troublesome, because the
> macro is going to grab some part of its input to give context to the
> non-hygienic identifier. In this case, `a-loop' uses the context of
> `count'.
>
> On the first iteration, `count' has the context that you want. On the
> second iteration, though, `count' has the context of `#,next', which is
> not what you want.
>
> Using `#,(datum->syntax-object (syntax count) next)' avoids the
> problem, at least for your example, by transferring the context of the
> original `count' to each `next'.
>
> Better yet, avoid the non-hygienic identifier. Using a syntax
> parameter, you can also avoid making code that uses `a-loop' supply an
> identifier to bind. Instead you end up with a single `it' binding whose
> meaning is adjusted by `a-loop':
>
> (require (lib "stxparam.ss"))
>
> (define-syntax-parameter it (lambda (stx)
> (raise-syntax-error
> #f
> "only valid in `a-loop'"
> stx)))
>
> (define-syntax (a-loop stx)
> (syntax-case stx (for)
> [(_ count body ...)
> (let ([done (equal? 0 (syntax-object->datum #'count))]
> [next (sub1 (syntax-object->datum #'count))])
> #`(let ([itid count])
> ;; Map `it' to `itid' for the body:
> (syntax-parameterize ([it (make-rename-transformer
> (quote-syntax itid))])
> #,(if done
> #'(begin body ...)
> #`(begin
> body ...
> (_ #,next body ...))))))]))
>
>
> > (a-loop 9 (display it))
> 9876543210
> > it
> it: only valid in `a-loop' in: it
>
>
> Matthew
>
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme