[racket] Macros with Flexible Sub-Forms like (class...)

From: Danny Yoo (dyoo at hashcollision.org)
Date: Sat Feb 23 15:19:38 EST 2013

On Sat, Feb 23, 2013 at 12:22 PM, Scott Klarenbach <scott at pointyhat.ca> wrote:
> What is the best approach for creating a macro that parses sub-forms in any
> order, similar to the way (class ...) works in Racket?


I believe that there's support in the syntax-parse library to parse
these sub-forms in any order.  Let me see if I can find the
appropriate documentation...  Ah, here:

    http://docs.racket-lang.org/syntax/Optional_Keyword_Arguments.html


The documentation here focuses on parsing optional keyword arguments
that can be consumed in any order.  The underlying mechanism should
work with non-keywords as well.


For example:


;;;;;;;;;;;;;;;;;;;;;;;;;
#lang racket

(require (for-syntax syntax/parse))

(struct person (name age) #:transparent)

;; Accept name and age in any order, or even omit them:
(define-syntax (new-person stx)
  (syntax-parse stx
    [(_ (~or (~optional ((~datum name) name) #:defaults ([name #'"Jane Doe"]))
             (~optional ((~datum age) age) #:defaults ([age #'#f])))
        ...)
     #'(person name age)]))

(new-person)

(new-person (name "Pen Pen"))

(new-person (age 48) (name "Gendo Ikari"))
;;;;;;;;;;;;;;;;;;;;;;;;;

Posted on the users mailing list.