Advanced syntax-rules Techniques
Limitations of syntax-rules: it can't compute (e.g., concatenate identifiers into a new name like point-x) or break hygiene intentionally. Use syntax-case or er/ir macros for those.
;; 1. Accumulator style: build up results across recursive expansions
(define-syntax my-reverse-list
(syntax-rules ()
((_ () (acc ...)) (list acc ...))
((_ (x rest ...) (acc ...)) (my-reverse-list (rest ...) (x acc ...)))))
(my-reverse-list (1 2 3) ()) ; (3 2 1)
;; 2. Vectors and dotted patterns
(define-syntax first-of-vector
(syntax-rules () ((_ #(a b ...)) 'a)))
(first-of-vector #(x y z)) ; x
;; 3. Custom ellipsis (R7RS): escape ... or rename it to write macro-defining macros
(define-syntax def-alias
(syntax-rules ()
((_ new old)
(define-syntax new
(syntax-rules ::: () ; use ::: as the ellipsis for the inner macro
((_ args :::) (old args :::)))))))
(def-alias plus +)
(plus 1 2 3) ; 6
;; (... ...) escapes an ellipsis inside a template
;; 4. Dispatching on internal keywords to structure expansion phases
(define-syntax my-define-record
(syntax-rules ()
((_ name field ...)
(begin
(define (name field ...) (vector 'name field ...))))))
;; 5. Common macros worth writing
(define-syntax inc!
(syntax-rules ()
((_ x) (set! x (+ x 1)))
((_ x n) (set! x (+ x n)))))
(d
…