[racket] Passing information between syntax classes

From: Greg Hendershott (greghendershott at gmail.com)
Date: Thu Feb 12 10:58:55 EST 2015

Preface: Whenever I attempt to answer a question about macros, my secret
agenda is that I'll be the main beneficiary... from someone else jumping
in to correct my answer and teach me. So here goes. :)

> I am trying to clean up some lengthy syntax-class definitions, but I
> am running into a problem. Here's a much-simplified example:
>
> ... snip ...
>
> I would need something like syntax-classes that take parameters, but I
> didn't find anything like that. Is there some other way to modularize
> my definition?

Does `bar` need to be a syntax-class? Instead, what if it's just another
macro -- that `foo` expands into, passing the set?

    #lang racket
    (require (for-syntax syntax/parse))

    (define-syntax (bar stx)
      (syntax-parse stx
        [((~datum bar) foo-symbols:expr bar-symbol:id)
         #'(list 'bar
                 (if (set-member? foo-symbols 'bar-symbol)
                     (list 'bar-symbol)
                     'bar-symbol))]))

    (define-syntax (foos-of-bars stx)
      (define-syntax-class foo
        (pattern ((~datum foo) foo-symbol:id ... ((~datum bar) bar-symbol:id) ...)
                 #:with value
                 #'(let ([foo-symbols (set 'foo-symbol ...)])
                     (list 'foo
                           (bar foo-symbols bar-symbol) ...))))
      (syntax-parse stx
        [(_ foo:foo ...)
         #'(list foo.value ...) ]))

    (foos-of-bars (foo x y (bar a) (bar x)))

Although this bakes the user/surface template for `bar` into the
template for `foo`, maybe that's acceptable for modularizing your own
definitions?

Posted on the users mailing list.