[racket] Syntax classes as first-class values

From: Jack Firth (jackhfirth at gmail.com)
Date: Tue Oct 21 15:04:23 EDT 2014

With syntax/parse, would it be possible to make syntax classes first class
values instead of just a macro extension on top of syntax parse? That way
you could parameterize syntax classes over arbitrary values, including
other syntax classes, to create composable syntax classes. For instance, I
find it very common when writing complex macros that I need to represent a
series of optional keyword clauses like so:

(define-syntax foo
  (syntax-parser
    [(_ req1 req2
         (~optional (~or (~seq #:kw1 op1)
                                 (~seq #:kw2 op2)
                                 (~seq #:kw3 op3)))
         ...)
     ; do something ]))

But this allows for items to be repeated and can be very verbose if the
clauses are complex. I can define a syntax class for each of the optional
clauses:

(define-splicing-syntax-class op1
  (pattern (~seq #:kw1 op1-pattern)))

(define-splicing-syntax-class op2
  ...
...

I'd like to also be able to define a function that takes those syntax
classes and returns a new syntax class representing an optional series of
any of those classes where each can be given once:

(define (optional-sequence-of class-a class-b class-c)
  (splicing-syntax-class
    (pattern (~optional (~or (~once (~var a class-a))
                                          (~once  (~var b class-b))
                                          (~once (~var c class-c)))) ...)))

And then my original macro would just be:

(define-syntax foo
  (syntax-parser
    [(_ req1 req2 (~var optionals optional-sequence-of op1 op2 op3))
    ; do something ]))

The reason I think this would be useful is that you could re-use the
optional-sequence-of class in other macros since it's generalized. You can
make some general "template" syntax classes for common macro tasks, such as
a sequence of pairs of unbound unique identifiers with expressions (for
let-like macros) or for a definition of a function's arguments (so Racket's
definition of a function ((f a b) g) and Typed Racket's definition of a
function ((f [a : Number] [b : Number]) [g : Number Number -> Number) could
re-use a lot of the same macro plumbing).

I don't know how possible this is, or what issues would need to be ironed
out to make it particularly useful, but I welcome any thoughts on the
matter.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20141021/fecdd2bb/attachment-0001.html>

Posted on the users mailing list.