[racket] Passing information between syntax classes

From: Konrad Hinsen (konrad.hinsen at fastmail.net)
Date: Thu Feb 12 09:53:54 EST 2015

I am trying to clean up some lengthy syntax-class definitions, but I
am running into a problem. Here's a much-simplified example:

----------------------------------------------------------------------
#lang racket

(require (for-syntax syntax/parse))

(define-syntax (foos-of-bars stx)

  (define-syntax-class foo
    #:attributes (value)
    (pattern ((~datum foo) foo-symbol:id ... ((~datum bar) bar-symbol:id) ...)
             #:with value
             #'(let ([foo-symbols (set (quote foo-symbol) ...)])
                 (list 'foo
                       (list 'bar
                             (if (set-member? foo-symbols (quote bar-symbol))
                                 (list (quote bar-symbol))
                                 (quote bar-symbol))) ...))))

  (syntax-parse stx
    [(_ foo:foo ...)
     #'(list foo.value ...) ]))

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

I have several patterns like 'foo', and they all share the same 'bar'
subpattern. Therefore I would like to make 'bar' a syntax class of its
own:

----------------------------------------------------------------------
(define-syntax (foos-of-bars stx)

  (define-syntax-class foo
    #:attributes (value)
    (pattern ((~datum foo) symbol:id ... bar:bar ...)
             #:with value
             #'(let ([foo-symbols (set (quote symbol)  ...)])
                 (list 'foo bar.value ...))))

  (define-syntax-class bar
    #:attributes (value)
    (pattern ((~datum bar) symbol:id)
             #:with value
             #'(list 'bar ???)))

  (syntax-parse stx
    [(_ foo:foo ...)
     #'(list foo.value ...) ]))
----------------------------------------------------------------------

The problem is what to put in place of the ???. With the split into
two syntax-classes, the expansion of 'bar' no longer has access to
'foo-symbols'.

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?

Konrad.

Posted on the users mailing list.