I've been trying to learn Racket macros but articles like this make me feel like I should just give up. For example, in arc a macro looks like this:
(mac awhen (expr . body)
`(let it ,expr (if it (do ,@body))))
I can understand that, and start making macros and going about my business. The Racket guys (e.g. Eli and Jay) write macros that look like this:
(require (lib "stxparam.ss" "mzlib"))
(define-syntax-parameter it
(lambda (stx)
(raise-syntax-error #f "can only be used inside `if'" stx)))
(define-syntax if*
(syntax-rules ()
[(if*) (void)]
[(if* X) X]
[(if* C X more ...)
(let ([b C])
(if b
(syntax-parameterize ([it (make-rename-transformer #'b)]) X)
(if* more ...)))]))
They have reasonable objections to arc-style macros, but I feel like they are overly academic and not relevant to the programming problems that I want to address. I want to eliminate boilerplate, and I'm willing to take the limitations of arc-style macros because they are so much easier to understand.
(define-syntax (awhen stx)
(syntax-case stx ()
((_ expr body ...)
(with-syntax ((it (datum->syntax stx 'it)))
#`(let ((it expr))
(when it body ...))))))
I find it a bit hairy, but mostly sane. It's all about being hygienic. Notice how you explicitly place the `it` identifier into the caller's context but keep the usual let and when?
This is Jay. Arc macros are like define-syntax-rule macros in Racket. dsr is great for lots of things, but sometimes you need more power.
In any case, this post is really about what's going on in the pattern matching and macro template underbelly, and not really a recommendation for how to program macros.