[racket] macro calling itself
I'm unclear why I'm getting an unbound-identifier error in this macro. I've written other self-referencing macros in the past that have worked, so I'm unclear why this one doesn't.
What I expect is that when `definer` is called with one argument, the first branch of `syntax-case` will stick on a default argument and call `definer` again. Which it does, except that in that case, it only binds the name 'id' rather than both 'id' and 'arg-id'.
#lang racket
(require (for-syntax racket/syntax) rackunit)
(define-syntax (definer stx)
(syntax-case stx ()
[(_ id)
#'(definer id zam)]
[(_ id arg)
(with-syntax ([arg-id (format-id stx "~a-~a" #'arg #'id)])
#'(begin
(define id (quote id))
(define arg-id (quote arg-id))))]))
(definer foo-id bar)
(check-equal? foo-id 'foo-id)
(check-equal? bar-foo-id 'bar-foo-id)
(definer baz-id)
(check-equal? baz-id 'baz-id)
(check-equal? zam-baz-id 'zam-baz-id) ;; unbound identifier error
OTOH, this version of the macro, which repeats the expansion template rather than calling itself, works fine:
#lang racket
(require (for-syntax racket/syntax) rackunit)
(define-syntax (definer2 stx)
(syntax-case stx ()
[(_ id)
(with-syntax ([arg-id (format-id stx "~a-~a" (format-id stx "zam") #'id)])
#'(begin
(define id (quote id))
(define arg-id (quote arg-id))))]
[(_ id arg)
(with-syntax ([arg-id (format-id stx "~a-~a" #'arg #'id)])
#'(begin
(define id (quote id))
(define arg-id (quote arg-id))))]))
(definer2 foo-id bar)
(check-equal? foo-id 'foo-id)
(check-equal? bar-foo-id 'bar-foo-id)
(definer2 baz-id)
(check-equal? baz-id 'baz-id)
(check-equal? zam-baz-id 'zam-baz-id) ;; no error this time