[plt-scheme] auxiliary macros

From: Vladimir Zlatanov (vlado at dikini.net)
Date: Tue Aug 7 07:29:44 EDT 2007

Ok, now I am confused, which is not a surprise, really.

As far as I understand this - the problem is that when specifying
yield in the original gets 'renamed' if the macro is used in other
macros due to hygiene rules.

Ryan's suggestion is to use syntax-parameter, which is a annotation
living in the syntax environment only, so it is not altered
by the hygiene rules. What is the utility of a syntax-parameter?
A syntax variable?

Matthias's solution is to augment the body0 syntax-object with the yield
binding
not the name. Since name might be a used in other contexts, so the resulting
yield
is identified to be used in the precisely right context. Hygiene rules won't
do
the wrong renames/tagging.

So you could define a kind of a rule of thumb - use the inner most possible
scope to introduce new identifiers.

Cheers,
Vlado

On 8/4/07, Matthias Felleisen <matthias at ccs.neu.edu> wrote:
>
> Vlado, you can, however, choose a different piece of context syntax
> for the introduction of the yield binding, namely, one from the
> scope you really want:
>
>   (define-syntax (define/y stx)
>    (syntax-case stx ()
>      [(_ (name arg ...) body0 body ...)
>       (with-syntax ((yield-name (datum->syntax-object #;stx (syntax
> body0) 'yield)))
>         (syntax
>          (define (name arg ...)
>            (define (yield-name x)
>              (control resume-here
>               (set! name
>                     (lambda ()
>                       (prompt (resume-here 'dummy))))
>               x))
>            (prompt body0 body ...))))]))
>
> If you now target this mini-language with a macro, the non-hygienic
> binding is introduced properly, e.g.,
>
>    (define-syntax foo
>      (syntax-rules ()
>       ((_ (name arg ...) body ...) (define/y (name arg ...) body ...))))
>
>    (foo (bar) (printf "hello world\n") (yield 1) (yield 2) 'finished)
>
>    (list (bar) (bar) (bar) (bar))
>
> -- Matthias
>
>
>
>
>
>
> On Aug 4, 2007, at 10:58 AM, Ryan Culpepper wrote:
>
> > On Fri, 2007-08-03 at 13:35 +0100, Vladimir Zlatanov wrote:
> >>
> >>         2. How can I use the macro system to eliminate the
> >>         'yield-name' part
> >>         of the macro?
> >>
> >> One solution that works, but I do have a few problems with it.
> >> I had to break the hygiene, which in this case might not be that bad,
> >> but it is not nice. More worringly for me, I'm not sure why does it
> >> really work the way it works. It is a problem with my
> >> understanding of
> >> macros, but that might pass with time =)
> >>
> >> What would be a hygienic solution?
> >
> > One problem with using 'datum->syntax-object' to introduce identifiers
> > (breaking hygiene) is that it often breaks down when you write another
> > macro that expands into the first one.
> >
> > For example, here's a trivial macro:
> >
> > (define-syntax define-gen
> >   (syntax-rules ()
> >     [(define-gen (name . args) . body)
> >      (make-gen (name . args) . body)]))
> >
> > Then use it:
> >
> > (define-gen (make-step)
> >   (yield 1)
> >   (yield 2)
> >   (yield 3)
> >   'finished)
> > (define step (make-step))
> > (step) ;;  produces error: undefined identifier 'yield'
> >
> > Why? The 'make-gen' identifier produced by 'define-gen' had a mark on
> > it, so the introduced 'yield' identifier had a mark on it, so it
> > didn't
> > bind the original, unmarked occurrences of 'yield'.
> >
> > One nice way to solve this problem is to use syntax parameters. There
> > was a thread on this list about them about a year ago, and I wrote
> > up a
> > summary here:
> >
> > http://macrologist.blogspot.com/2006/04/macros-parameters-binding-
> > and.html
> >
> > There's more information in the Help Desk: search for
> > 'syntax-parameterize'.
> >
> > Ryan
> >
> >
> >>
> >> ===========================
> >> (require (lib "control.ss"))
> >>
> >> (define-syntax (make-gen stx)
> >>   (syntax-case stx ()
> >>     [(mkg (name arg ...) body ...)
> >>      (syntax-case (datum->syntax-object (syntax mkg) 'yield) ()
> >>        [yield (syntax
> >>                (define (name arg ...)
> >>                  (define (control-state) body ...)
> >>                  (define (yield value) (control resume-here (set!
> >> control-state resume-here) value))
> >>                  (lambda () (prompt (control-state)))))])]))
> >>
> >> (make-gen (make-step)
> >>           (yield 1)
> >>           (yield 2)
> >>           (yield 3)
> >>           'finished)
> >>
> >> (define step (make-step))
> >>
> >> (step)(step)(step)(step)(step)
> >>
> >> ===========================
> >>
> >> _________________________________________________
> >>   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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20070807/94b06f18/attachment.html>

Posted on the users mailing list.