I have created a splicing syntax class that captures keyword options that may be provided in any order. Using the ~optional ellipsis head pattern makes this easy enough:
(define-splicing-syntax-class opts (pattern (~seq (~or (~optional (~seq #:a a)) (~optional (~seq #:b b)) (~optional (~seq #:x x)) (~optional (~seq #:y y))) ...)) However, there is a catch: I want to be able to *group* these options into two sets: the group containing `a` and `b`, and the group containing `x` and `y`. However, the user may still specify the options in any order, so for this example input: (foobar #:b 3 #:y 7 #:a 2) I want to be able to produce the following attributes: first-opts: (#:a 2 #:b 3) second-opts: (#:y 7) So far, I’ve managed to do this manually using #:with, but it isn’t pretty: (define-splicing-syntax-class opts #:attributes ([first-opts 1] [second-opts 1]) (pattern (~seq (~or (~optional (~seq #:a a)) (~optional (~seq #:b b)) (~optional (~seq #:x x)) (~optional (~seq #:y y))) ...) #`(#,@(if (attribute a) #'(#:a a) #'()) #,@(if (attribute b) #'(#:b b) #'())) #:with (second-opts ...) #`(#,@(if (attribute x) #'(#:x x) #'()) #,@(if (attribute y) #'(#:y y) #'())))) This can be simplified a little bit using `template` from syntax/parse/experimental/template: (define-splicing-syntax-class opts #:attributes ([first-opts 1] [second-opts 1]) (pattern (~seq (~or (~optional (~seq #:a a)) (~optional (~seq #:b b)) (~optional (~seq #:x x)) (~optional (~seq #:y y))) ...) #:with (first-opts ...) (template ((?? (?@ #:a a)) (?? (?@ #:b b)))) #:with (second-opts ...) (template ((?? (?@ #:a x)) (?? (?@ #:b y)))))) However, this is really just some sugar for the above, and it doesn’t actually address the problem of having to enumerate each option in each clause. If I, for example, added a #:c option, I would need to remember to add it to the `first-opts` group, otherwise it would be completely ignored. What I *really* want is some declarative way to group these sets of optional values. For example, I’d like a syntax like this: (define-splicing-syntax-class opts #:attributes ([first-opts 1] [second-opts 1]) (pattern (~seq (~or (~group first-opts (~optional (~seq #:a a)) (~optional (~seq #:b b))) (~group second-opts (~optional (~seq #:x x)) (~optional (~seq #:y y)))) ...))) Or, even better, it would be nice if I could use existing primitives, something like this: (define-splicing-syntax-class opts #:attributes ([first-opts 1] [second-opts 1]) (pattern (~seq (~or (~and first-opts (~seq (~optional (~seq #:a a)) (~optional (~seq #:b b)))) (~and second-opts (~seq (~optional (~seq #:x x)) (~optional (~seq #:y y))))) ...))) However, neither of those work. Is there any way to do this using the builtins provided by syntax/parse? If not, is there any simple way to define something like ~group myself? Thanks, Alexis (also asked as http://stackoverflow.com/q/34551203/465378) -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.