Factor out parts of syntax templates

Something else to be aware of: when using syntax classes, you can use attributes to move some of the "assembly logic" of your macro into the syntax class. Also, you can use splicing syntax classes to make a single syntax class match a sequence of terms instead of a single term. Putting that together:

(begin-for-syntax
  (define-splicing-syntax-class helper
    #:attributes (as-list-expression)
    (pattern (~seq stuff:expr ...)
      #:with as-list-expression #'(list stuff ...)))

(define-syntax (main-macro stx)
  (syntax-parse stx
    [(_ stuff-sequence:helper)
     #'stuff-sequence.as-list-exprssion]))

(main-macro 1 2 3) ;=> (list 1 2 3)

Also, you can use define-syntax-parse-rule (from the syntax/parse/define module) as a shortcut for (define-syntax (macro stx) (syntax-parse stx [pattern #'template])) like so:

(require syntax/parse/define)

(define-syntax-parse-rule (main-macro stuff-sequence:helper)
  stuff-sequence.as-list-expression)

For these reasons, syntax classes are the first tool I recommend reaching for when you're trying to make a macro simpler by moving some of its logic into helpers. And if you make a habit of doing that, almost all of your macros can be written with define-syntax-parse-rule.

5 Likes