[racket] Passing information between syntax classes

From: Jens Axel Søgaard (jensaxel at soegaard.net)
Date: Thu Feb 12 12:02:45 EST 2015

Since the expansion of (bar x) depends on the identifiers
in the surrounding usage of foo, one solution is to use
syntax-parameters that adjust the meaning of (bar x)
according to the context in which it appears.

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

(define-syntax-parameter bar
  (λ (stx)
    (raise-syntax-error 'bar "bar keyword used outside foo" stx)))

  (define-syntax-class bar-expr
    (pattern ((~datum bar) x:id))))

(define-syntax (my-foos-of-bars stx)
  (syntax-parse stx
    [(_ ((~datum foo) foo-id:id ... e:bar-expr ...))
        ([bar (λ (stx)
                (syntax-parse stx
                  [(_bar x:id)
                   (if (memq (syntax-e #'x) '(foo-id ...))
                       #'(list 'x)
        (list 'foo e ...))]))

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

2015-02-12 17:16 GMT+01:00 Konrad Hinsen <konrad.hinsen at fastmail.net>:
> Greg Hendershott writes:
>  > 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. :)
> Fair enough ;-)
>  > Does `bar` need to be a syntax-class? Instead, what if it's just another
>  > macro -- that `foo` expands into, passing the set?
> Introducing another macro lets me factor out the expansion of "bar",
> but not the pattern itself. In my case, it would already yield some
> benefits, so I'll keep this solution in mind if nothing better comes up.
> But ideally, I would like to factor out the pattern itself, which in
> my real application is more complex and consists of several cases.
> Thanks,
>   Konrad.
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users

Jens Axel Søgaard

Posted on the users mailing list.