[plt-scheme] auxiliary macros

From: Ryan Culpepper (ryanc at ccs.neu.edu)
Date: Sat Aug 4 10:58:17 EDT 2007

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



Posted on the users mailing list.